132 lines
3.6 KiB
HLSL
132 lines
3.6 KiB
HLSL
|
|
texture2D gShadowMap : ShadowMap;
|
|
float4x4 gLightWorldViewProj : 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 gShadowSampler2 : ShadowSampler {
|
|
Filter = MIN_MAG_MIP_POINT;
|
|
AddressU = CLAMP;
|
|
AddressV = CLAMP;
|
|
ComparisonFunc = LESS_EQUAL;
|
|
};
|
|
|
|
|
|
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) , gLightWorldViewProj);
|
|
return output;
|
|
}
|
|
|
|
// Shadow sampling function
|
|
float ShadowCalculation(float4 shadowCoord, float3 normal) {
|
|
// 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, gLightDirection)), 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 {
|
|
float shadowFactor = ShadowCalculation(input.ShadowCoord, input.Normal);
|
|
|
|
float3 diffuseColor = gDiffuseMap.Sample(gSampleState, input.TexCoord).rgb;
|
|
|
|
float3 finalColor = float3(1.f, 1.f, 1.f) * shadowFactor;
|
|
finalColor += gAmbient;
|
|
|
|
return float4(finalColor, 1.0f);
|
|
}
|
|
|
|
// 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()));
|
|
}
|
|
}
|