// Global parameters SamplerState gShadowSampler : ShadowSampler; SamplerState gShadowSampler2 : ShadowSampler { Filter = MIN_MAG_MIP_POINT; AddressU = CLAMP; AddressV = CLAMP; ComparisonFunc = LESS_EQUAL; }; texture2D gShadowMap : ShadowMap; float4x4 gLightViewProj : LightViewProjection; DepthStencilState ShadowDepthStencilState { DepthEnable = true; DepthWriteMask = ALL; // Write depth to the shadow map DepthFunc = LESS_EQUAL; // Compare depth in the shadow map StencilEnable = false; // We don't need stencil operations here }; SamplerState gSampleState : SampleState; RasterizerState gRasterizerState : RastState; float4x4 gWorldViewProj : WorldViewProjection; float4x4 gWorldMatrix : WorldMatrix; texture2D gDiffuseMap : DiffuseMap; texture2D gNormalMap : Normal; texture2D gSpecularMap : Specular; texture2D gGlossMap : Gloss; float3 gLightDirection : LightDirection; float3 gLightColor : LightColor; float3 gCameraPosition : CameraPosition; bool gUseNormal : UseNormal; static const float3 gAmbient = float3(.03f, .03f, .03f); // Input output structures struct VS_INPUT { float3 Position : POSITION; float2 TexCoord : TEXCOORD; float3 Normal : NORMAL; float3 Tangent : TANGENT; }; struct VS_OUTPUT { float4 Position : SV_POSITION; float4 WorldPosition : WORLDPOSITION; float2 TexCoord : TEXCOORD; float3 Normal : NORMAL; float3 Tangent : TANGENT; float4 ShadowCoord : SHADOWCOORD; // Add this to store shadow map coordinates }; // Vertex shader VS_OUTPUT VS(VS_INPUT input) { VS_OUTPUT output = (VS_OUTPUT)0; output.WorldPosition = mul(float4(input.Position, 1.f), gWorldMatrix); output.Position = mul(float4(input.Position, 1.f), gWorldViewProj); output.TexCoord = input.TexCoord; output.Normal = mul(input.Normal, (float3x3) gWorldMatrix); output.Tangent = mul(input.Tangent, (float3x3) gWorldMatrix); // Calculate shadow map coordinates // lightSpaceMatrix * vec4(vs_out.FragPos, 1.0); output.ShadowCoord = mul(float4(input.Position, 1.f) , gLightViewProj); return output; } // Shadow sampling function float ShadowCalculation(float4 shadowCoord) { // Normalize the depth by dividing by the w component float3 projCoord = shadowCoord.xyz / shadowCoord.w; // Convert from [-1, 1] to [0, 1] float2 UVCoords; UVCoords.x = 0.5f * projCoord.x + 0.5f; UVCoords.y = -0.5f * projCoord.y + 0.5f; // float z = 0.5 * projCoord.z + 0.5; float z = projCoord.z; // Sample the shadow map float shadowDepth = gShadowMap.Sample(gShadowSampler2, UVCoords.xy).r; float bias = 0.0025f; // float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005); // return gShadowMap.Sample(gShadowSampler2, UVCoords.xy).r; // Check if the current fragment is in shadow if (shadowDepth + bias < z) return 0.5f; else return 1.0f; } // Pixel shader float4 PS(VS_OUTPUT input) : SV_TARGET { // Check if gDiffuseMap sample has a valid value, otherwise render red // if (gDiffuseMap.Sample(gSampleState, input.TexCoord).a == 0.f) // return float4(1.f, 0.f, 0.f, 1.f); // return float4(Shade(input), 1.0f); // Use the shading function with shadow // return gShadowMap.Sample(gShadowSampler, input.ShadowCoord.xy / input.ShadowCoord.w); // Sample shadow map float shadowFactor = ShadowCalculation(input.ShadowCoord); float3 diffuseColor = gDiffuseMap.Sample(gSampleState, input.TexCoord).rgb; float3 finalColor = float3(1.f, 1.f, 1.f) * shadowFactor; finalColor += gAmbient; // return float4(shadowDepth,shadowDepth,shadowDepth, 1.0f); return float4(finalColor, 1.0f); // return gShadowMap.Sample(gShadowSampler, input.TexCoord); // Sample shadow map } // DepthStencilState DepthStencilState gDepthStencilState { DepthEnable = true; DepthWriteMask = ALL; DepthFunc = LESS; StencilEnable = true; }; // Technique technique11 DefaultTechnique { pass P0 { SetDepthStencilState(ShadowDepthStencilState, 0); SetRasterizerState(gRasterizerState); SetVertexShader(CompileShader(vs_5_0, VS())); SetGeometryShader(NULL); SetPixelShader(CompileShader(ps_5_0, PS())); } }