//----------------------------------------------------------------------------- // Lighting.fxh // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- struct ColorPair { float3 Diffuse; float3 Specular; }; ColorPair ComputeLights(float3 eyeVector, float3 worldNormal, uniform int numLights) { float3x3 lightDirections = 0; float3x3 lightDiffuse = 0; float3x3 lightSpecular = 0; float3x3 halfVectors = 0; [unroll] for (int i = 0; i < numLights; i++) { lightDirections[i] = float3x3(DirLight0Direction, DirLight1Direction, DirLight2Direction) [i]; lightDiffuse[i] = float3x3(DirLight0DiffuseColor, DirLight1DiffuseColor, DirLight2DiffuseColor) [i]; lightSpecular[i] = float3x3(DirLight0SpecularColor, DirLight1SpecularColor, DirLight2SpecularColor)[i]; halfVectors[i] = normalize(eyeVector - lightDirections[i]); } float3 dotL = mul(-lightDirections, worldNormal); float3 dotH = mul(halfVectors, worldNormal); float3 zeroL = step(0, dotL); float3 diffuse = zeroL * dotL; float3 specular = pow(max(dotH, 0) * zeroL, SpecularPower); ColorPair result; result.Diffuse = mul(diffuse, lightDiffuse) * DiffuseColor.rgb + EmissiveColor; result.Specular = mul(specular, lightSpecular) * SpecularColor; return result; } CommonVSOutput ComputeCommonVSOutputWithLighting(float4 position, float3 normal, uniform int numLights) { CommonVSOutput vout; float4 pos_ws = mul(position, World); float3 eyeVector = normalize(EyePosition - pos_ws.xyz); float3 worldNormal = normalize(mul(normal, WorldInverseTranspose)); ColorPair lightResult = ComputeLights(eyeVector, worldNormal, numLights); vout.Pos_ps = mul(position, WorldViewProj); vout.Diffuse = float4(lightResult.Diffuse, DiffuseColor.a); vout.Specular = lightResult.Specular; vout.FogFactor = ComputeFogFactor(position); return vout; } struct CommonVSOutputPixelLighting { float4 Pos_ps; float3 Pos_ws; float3 Normal_ws; float FogFactor; }; CommonVSOutputPixelLighting ComputeCommonVSOutputPixelLighting(float4 position, float3 normal) { CommonVSOutputPixelLighting vout; vout.Pos_ps = mul(position, WorldViewProj); vout.Pos_ws = mul(position, World).xyz; vout.Normal_ws = normalize(mul(normal, WorldInverseTranspose)); vout.FogFactor = ComputeFogFactor(position); return vout; } #define SetCommonVSOutputParamsPixelLighting \ vout.PositionPS = cout.Pos_ps; \ vout.PositionWS = float4(cout.Pos_ws, cout.FogFactor); \ vout.NormalWS = cout.Normal_ws;