improve shadow process, now shadow can render according to the camera position

This commit is contained in:
2026-04-07 13:20:02 +08:00
parent 3c64abd77e
commit 230957f728
5 changed files with 309 additions and 274 deletions

View File

@ -362,44 +362,38 @@ vec3 IBL(vec3 F0, vec3 Lr)
}
// shadow
float calculateShadow(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir)
{
// Perspective divide
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
// Transform to [0,1] range
projCoords = projCoords * 0.5 + 0.5;
// If outside shadow map bounds, assume no shadow
if(projCoords.z > 1.0 || projCoords.x < 0.0 || projCoords.x > 1.0 || projCoords.y < 0.0 || projCoords.y > 1.0)
if (projCoords.z > 1.0 || projCoords.x < 0.0 || projCoords.x > 1.0 ||
projCoords.y < 0.0 || projCoords.y > 1.0)
return 0.0;
// Get closest depth value from light's perspective
float closestDepth = texture(u_ShadowMap, projCoords.xy).r;
float currentDepth = projCoords.z;
// Calculate bias based on surface angle
float bias = max(u_ShadowBias * (1.0 - dot(normal, lightDir)), u_ShadowBias * 0.1);
// PCF (Percentage Closer Filtering) for soft shadows
float shadow = 0.0;
vec2 texelSize = 1.0 / textureSize(u_ShadowMap, 0);
int pcfRange = int(u_ShadowSoftness);
int sampleCount = 0;
int pcfRange = clamp(int(u_ShadowSoftness), 0, 3);
for(int x = -pcfRange; x <= pcfRange; ++x)
vec2 texelSize = 1.0 / textureSize(u_ShadowMap, 0);
float shadow = 0.0;
int samples = 0;
for (int x = -pcfRange; x <= pcfRange; ++x)
{
for(int y = -pcfRange; y <= pcfRange; ++y)
for (int y = -pcfRange; y <= pcfRange; ++y)
{
float pcfDepth = texture(u_ShadowMap, projCoords.xy + vec2(x, y) * texelSize).r;
shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0;
sampleCount++;
vec2 offset = vec2(x, y) * texelSize;
float pcfDepth = texture(u_ShadowMap, projCoords.xy + offset).r;
shadow += (currentDepth - bias) > pcfDepth ? 1.0 : 0.0;
samples++;
}
}
shadow /= float(sampleCount);
return shadow;
shadow /= float(samples);
return shadow * u_ShadowIntensity;
}

View File

@ -347,44 +347,38 @@ vec3 IBL(vec3 F0, vec3 Lr)
}
// shadow
float calculateShadow(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir)
{
// Perspective divide
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
// Transform to [0,1] range
projCoords = projCoords * 0.5 + 0.5;
// If outside shadow map bounds, assume no shadow
if(projCoords.z > 1.0 || projCoords.x < 0.0 || projCoords.x > 1.0 || projCoords.y < 0.0 || projCoords.y > 1.0)
if (projCoords.z > 1.0 || projCoords.x < 0.0 || projCoords.x > 1.0 ||
projCoords.y < 0.0 || projCoords.y > 1.0)
return 0.0;
// Get closest depth value from light's perspective
float closestDepth = texture(u_ShadowMap, projCoords.xy).r;
float currentDepth = projCoords.z;
// Calculate bias based on surface angle
float bias = max(u_ShadowBias * (1.0 - dot(normal, lightDir)), u_ShadowBias * 0.1);
// PCF (Percentage Closer Filtering) for soft shadows
float shadow = 0.0;
vec2 texelSize = 1.0 / textureSize(u_ShadowMap, 0);
int pcfRange = int(u_ShadowSoftness);
int sampleCount = 0;
int pcfRange = clamp(int(u_ShadowSoftness), 0, 3);
for(int x = -pcfRange; x <= pcfRange; ++x)
vec2 texelSize = 1.0 / textureSize(u_ShadowMap, 0);
float shadow = 0.0;
int samples = 0;
for (int x = -pcfRange; x <= pcfRange; ++x)
{
for(int y = -pcfRange; y <= pcfRange; ++y)
for (int y = -pcfRange; y <= pcfRange; ++y)
{
float pcfDepth = texture(u_ShadowMap, projCoords.xy + vec2(x, y) * texelSize).r;
shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0;
sampleCount++;
vec2 offset = vec2(x, y) * texelSize;
float pcfDepth = texture(u_ShadowMap, projCoords.xy + offset).r;
shadow += (currentDepth - bias) > pcfDepth ? 1.0 : 0.0;
samples++;
}
}
shadow /= float(sampleCount);
return shadow;
shadow /= float(samples);
return shadow * u_ShadowIntensity;
}