#include "../fxh/Constants.fxh" #include "../fxh/Lighting.fxh" // Lighting state float4 g_DirectionalLightAmbient[MAX_DIRECTIONAL_LIGHTS] : DirectionalLightAmbient; float4 g_DirectionalLightDiffuse[MAX_DIRECTIONAL_LIGHTS] : DirectionalLightDiffuse; float3 g_DirectionalLightDirection[MAX_DIRECTIONAL_LIGHTS] : DirectionalLightDirection; bool g_DirectionalLightEnabled[MAX_DIRECTIONAL_LIGHTS] : DirectionalLightEnabled; float4 g_DirectionalLightSpecular[MAX_DIRECTIONAL_LIGHTS] : DirectionalLightSpecular; // Camera float3 g_CameraPosition : CameraPosition; // Current material Material g_Material : Material; // Transforms float4x4 g_WorldViewProjection : WorldViewProjection; float4x4 g_World : World; struct VS_OUTPUT { float4 Pos : POSITION; float4 Diffuse : COLOR0; float4 Specular : COLOR1; float4 Tex0 : TEXCOORD0; }; float4 CalculateAmbientLight() { float4 ambient = 0; for (int i = 0; i < MAX_DIRECTIONAL_LIGHTS; i++) { if (g_DirectionalLightEnabled[i]) { ambient += g_DirectionalLightAmbient[i]; } } return ambient; } float4 CalculateDiffuse(float3 N, float3 L, float4 diffuseColor) { float NDotL = dot(N, L); float4 finalColor = 0; if (NDotL > 0.0f) { finalColor = max(0, NDotL * diffuseColor); } return finalColor; } float4 CalculateSpecular(float3 worldPos, float3 N, float3 L, float4 specularColor) { float4 finalColor = 0; if (g_Material.Power > 0) { float3 toEye = normalize(g_CameraPosition.xyz - worldPos); float3 halfway = normalize(toEye + L); float NDotH = saturate(dot(halfway, N)); finalColor = max(0, pow(NDotH, g_Material.Power) * specularColor); } return finalColor; } Lighting DoDirectionalLight(float3 worldPos, float3 N, int i) { Lighting Out; Out.Diffuse = CalculateDiffuse( N, -g_DirectionalLightDirection[i], g_DirectionalLightDiffuse[i]); Out.Specular = CalculateSpecular( worldPos, N, -g_DirectionalLightDirection[i], g_DirectionalLightSpecular[i]); return Out; } Lighting ComputeLighting(float3 worldPos, float3 N) { Lighting finalLighting = (Lighting)0; for (int i = 0; i < MAX_DIRECTIONAL_LIGHTS; i++) { if (g_DirectionalLightEnabled[i]) { Lighting lighting = DoDirectionalLight(worldPos, N, i); finalLighting.Diffuse += lighting.Diffuse; finalLighting.Specular += lighting.Specular; } } float4 ambient = g_Material.Ambient * CalculateAmbientLight(); float4 diffuse = g_Material.Diffuse * finalLighting.Diffuse; float4 specular = g_Material.Specular * finalLighting.Specular; finalLighting.Diffuse = saturate(ambient + diffuse); finalLighting.Specular = saturate(specular); return finalLighting; } //----------------------------------------------------------------------------- // Name: DoPointLight() // Desc: Point light computation //----------------------------------------------------------------------------- //COLOR_PAIR DoPointLight(float4 vPosition, float3 N, float3 V, int i) //{ // float3 L = mul((float3x3)matViewIT, normalize((lights[i].vPos-(float3)mul(matWorld,vPosition)))); // COLOR_PAIR Out; // float NdotL = dot(N, L); // Out.Color = lights[i].vAmbient; // Out.Specular = 0; // float fAtten = 1.f; // if(NdotL >= 0.f) // { // //compute diffuse color // Out.Color += NdotL * lights[i].vDiffuse; // // //add specular component // if(bSpecular) // { // float3 H = normalize(L + V); //half vector // Out.Specular = pow(max(0, dot(H, N)), fMaterialPower) * lights[i].vSpecular; // } // // float LD = length(lights[i].vPos-(float3)mul(matWorld,vPosition)); // if(LD > lights[i].fRange) // { // fAtten = 0.f; // } // else // { // fAtten *= 1.f/(lights[i].vAttenuation.x + lights[i].vAttenuation.y*LD + lights[i].vAttenuation.z*LD*LD); // } // Out.Color *= fAtten; // Out.Specular *= fAtten; // } // return Out; //} VS_OUTPUT VSMain ( float4 vPosition : POSITION0, float3 vNormal : NORMAL0, float2 tc : TEXCOORD0) { VS_OUTPUT Out = (VS_OUTPUT)0; vNormal = normalize(vNormal); Out.Pos = mul(vPosition, g_WorldViewProjection); //automatic texture coordinate generation Out.Tex0.xy = tc; //directional lights float4 worldPos = mul(vPosition, g_World); //position in view space float3 normal = mul(vNormal, (float3x3)g_World); Lighting lighting = ComputeLighting(worldPos, normal); ////point lights //for(int i = 0; i < iLightPointNum; i++) //{ // COLOR_PAIR ColOut = DoPointLight(vPosition, N, V, i+iLightPointIni); // Out.Color += ColOut.Color; // Out.Specular += ColOut.Specular; //} Out.Diffuse = lighting.Diffuse; Out.Specular = lighting.Specular; return Out; } float4 ps_main(VS_OUTPUT input) : COLOR0 { return input.Diffuse; } technique TexturedVertexLighting { pass P0 { //PixelShader = compile ps_2_0 ps_main(); VertexShader = compile vs_2_0 VSMain(); } }