Shadows go brrr
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user