Shadows go brrr

This commit is contained in:
2025-01-16 14:03:28 +01:00
parent 8a3bf57d7e
commit 071caf51b6
22 changed files with 4140 additions and 3269 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,35 +1,41 @@
// 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;
// Transformations
float4x4 gWorldViewProj : WorldViewProjection;
float4x4 gWorldMatrix : WorldMatrix;
float4x4 gLightViewProj : LightViewProjection;
// Textures
texture2D gDiffuseMap : DiffuseMap;
texture2D gNormalMap : Normal;
texture2D gSpecularMap : Specular;
texture2D gGlossMap : Gloss;
texture2D gShadowMap : ShadowMap;
// Light properties
float3 gLightDirection : LightDirection;
float3 gLightColor : LightColor;
float3 gCameraPosition : CameraPosition;
bool gUseNormal : UseNormal;
// Constants
static const float3 gAmbient = float3(.03f, .03f, .03f);
static const float gLightIntensity = 7.f;
static const float PI = 3.14159f;
static const float gSpecularReflectance = 1.f;
static const float gShininess = 25.f;
// Shadow bias to reduce artifacts
static const float gShadowBias = 0.005f;
// Input/Output structures
// Input output structures
struct VS_INPUT {
float3 Position : POSITION;
float2 TexCoord : TEXCOORD;
@@ -43,66 +49,90 @@ struct VS_OUTPUT {
float2 TexCoord : TEXCOORD;
float3 Normal : NORMAL;
float3 Tangent : TANGENT;
float4 LightPosition : TEXCOORD1;
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.Position = mul(float4(input.Position, 1.f), gWorldViewProj);
output.WorldPosition = mul(float4(input.Position, 1.f), gWorldMatrix);
output.TexCoord = input.TexCoord;
output.Normal = mul(input.Normal, (float3x3)gWorldMatrix);
output.Tangent = mul(input.Tangent, (float3x3)gWorldMatrix);
output.LightPosition = mul(float4(input.Position, 1.f), gLightViewProj);
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;
}
float ShadowCalculation(float4 lightPos) {
// Transform light position to shadow map space
float2 shadowCoord = lightPos.xy / lightPos.w;
shadowCoord = shadowCoord * 0.5f + 0.5f;
// 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(gSampleState, shadowCoord).r;
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;
// Compare depth and apply bias
if (shadowDepth + gShadowBias < lightPos.z / lightPos.w) {
return 0.0f; // In shadow
}
return 1.0f; // Not in shadow
}
// Pixel shader
float4 PS(VS_OUTPUT input) : SV_TARGET {
// Normalize inputs
float3 normal = normalize(input.Normal);
float3 lightDir = normalize(gLightDirection);
// 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);
// Diffuse lighting
float NdotL = max(dot(normal, -lightDir), 0.0f);
float3 diffuse = gLightColor * NdotL;
// return float4(Shade(input), 1.0f); // Use the shading function with shadow
// Shadows
float shadowFactor = ShadowCalculation(input.LightPosition);
// return gShadowMap.Sample(gShadowSampler, input.ShadowCoord.xy / input.ShadowCoord.w); // Sample shadow map
// Ambient + Diffuse * Shadow
float3 finalColor = gAmbient + (diffuse * shadowFactor);
// float3 finalColor = float3(shadowFactor,shadowFactor,shadowFactor);
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 gDepthStencilState {
// DepthStencilState
DepthStencilState gDepthStencilState
{
DepthEnable = true;
DepthWriteMask = ALL;
DepthFunc = LESS;
StencilEnable = true;
};
// Technique
technique11 DefaultTechnique {
pass P0 {
SetDepthStencilState(gDepthStencilState, 0);
SetDepthStencilState(ShadowDepthStencilState, 0);
SetRasterizerState(gRasterizerState);
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);

View File

@@ -1,10 +1,6 @@
float4x4 gLightWorldViewProj : WorldViewProjection;
float4x4 gWorldViewProj: WorldViewProjection; //For compatibility sake
Texture2D gShadowMap : ShadowMap;
SamplerState gShadowMapSampler : ShadowMapSampler;
struct VS_Input {
float3 Position : POSITION;
float2 TexCoord : TEXCOORD;
@@ -27,14 +23,24 @@ VS_Output VS_Shadow(VS_Input input)
float4 PS_Shadow(VS_Output input) : SV_TARGET
{
// Output depth information (Z/W in clip space)
return float4(input.Position.z / input.Position.w, 0.0f, 0.0f, 1.0f);
// // gl_FragDepth = gl_FragCoord.z;
return float4(input.Position.z / input.Position.w, 0.0f, 0.0f, input.Position.z / input.Position.w);
}
// Rasterizer state for front face culling
RasterizerState FrontFaceCull
{
FrontCounterClockwise = FALSE;
CullMode = FRONT;
};
// Technique for rendering shadow map
technique11 DefaultTechnique
{
pass P0
{
//Set FrontFaceCulling
SetRasterizerState(FrontFaceCull);
SetVertexShader(CompileShader(vs_5_0, VS_Shadow()));
SetPixelShader(CompileShader(ps_5_0, PS_Shadow()));
}