#include "Macros.fxh" //from FNA // Effect applies normalmapped lighting to a 2D sprite. DECLARE_TEXTURE(Texture, 0); DECLARE_TEXTURE(Normal, 1); BEGIN_CONSTANTS float AmbientColor _ps(c0) _cb(c0); float3 PointLightPositions[8] _ps(c1) _cb(c1); float3 PointLightColors[8] _ps(c9) _cb(c9); float DirectionalLightDirection _ps(c17) _cb(c17); float DirectionalLightColor _ps(c18) _cb(c18); MATRIX_CONSTANTS float4x4 WorldInverseTranspose _ps(c19) _cb(c19); float4x4 World _vs(c0) _cb(c23); float4x4 WorldViewProjection _vs(c4) _cb(c27); END_CONSTANTS struct VertexShaderInput { float4 Position : POSITION; float2 TexCoord : TEXCOORD0; }; struct PixelShaderInput { float4 Position : SV_Position; float2 TexCoord : TEXCOORD0; float3 PositionWS : TEXCOORD2; }; PixelShaderInput main_vs(VertexShaderInput input) { PixelShaderInput output; output.TexCoord = input.TexCoord; output.PositionWS = mul(input.Position, World).xyz; output.Position = mul(input.Position, WorldViewProjection); return output; } float4 main_ps(PixelShaderInput input) : COLOR0 { // Look up the texture and normalmap values. float4 tex = tex2D(TextureSampler, input.TexCoord); float3 normal = tex2D(NormalSampler, input.TexCoord).xyz; float3 normalWS = mul(normal, (float3x3)WorldInverseTranspose).xyz; float3 lightColor = float3(0.0, 0.0, 0.0); // point lights for (int i = 0; i < 8; i++) { float3 lightVec = PointLightPositions[i] - input.PositionWS; float distance = length(lightVec); float3 lightDir = normalize(lightVec); float diffuse = max(dot(normalWS, lightDir), 0.0); float3 attenuation = 1.0 / (distance * distance); lightColor += diffuse * attenuation * PointLightColors[i]; } // directional light float directionalDiffuse = max(dot(normalWS, DirectionalLightDirection), 0.0); lightColor += directionalDiffuse * DirectionalLightColor; // ambient light lightColor += AmbientColor; // blend with sample return tex * float4(lightColor, 1.0); } Technique DiffuseLitSprite { pass { VertexShader = compile vs_3_0 main_vs(); PixelShader = compile ps_3_0 main_ps(); } }