mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
- Added linear and nearest shadowmap filters (enabled with defines)
This commit is contained in:
parent
4afface97c
commit
a6d4bfc748
1 changed files with 48 additions and 7 deletions
|
@ -138,27 +138,57 @@ float R_DoomLightingEquation(float light)
|
|||
|
||||
#ifdef SUPPORTS_SHADOWMAPS
|
||||
|
||||
float sampleShadowmap(vec2 dir, float v)
|
||||
float shadowDirToU(vec2 dir)
|
||||
{
|
||||
float u;
|
||||
if (abs(dir.x) > abs(dir.y))
|
||||
{
|
||||
if (dir.x >= 0.0)
|
||||
u = dir.y / dir.x * 0.125 + (0.25 + 0.125);
|
||||
return dir.y / dir.x * 0.125 + (0.25 + 0.125);
|
||||
else
|
||||
u = dir.y / dir.x * 0.125 + (0.75 + 0.125);
|
||||
return dir.y / dir.x * 0.125 + (0.75 + 0.125);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dir.y >= 0.0)
|
||||
u = dir.x / dir.y * 0.125 + 0.125;
|
||||
return dir.x / dir.y * 0.125 + 0.125;
|
||||
else
|
||||
u = dir.x / dir.y * 0.125 + (0.50 + 0.125);
|
||||
return dir.x / dir.y * 0.125 + (0.50 + 0.125);
|
||||
}
|
||||
}
|
||||
|
||||
float sampleShadowmap(vec2 dir, float v)
|
||||
{
|
||||
float u = shadowDirToU(dir);
|
||||
float dist2 = dot(dir, dir);
|
||||
return texture(ShadowMap, vec2(u, v)).x > dist2 ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
float sampleShadowmapLinear(vec2 dir, float v)
|
||||
{
|
||||
float u = shadowDirToU(dir);
|
||||
float dist2 = dot(dir, dir);
|
||||
|
||||
vec2 isize = textureSize(ShadowMap, 0);
|
||||
vec2 size = vec2(isize);
|
||||
|
||||
vec2 fetchPos = vec2(u, v) * size - vec2(0.5, 0.0);
|
||||
if (fetchPos.x < 0.0)
|
||||
fetchPos.x += size.x;
|
||||
|
||||
ivec2 ifetchPos = ivec2(fetchPos);
|
||||
int y = ifetchPos.y;
|
||||
|
||||
float t = fract(fetchPos.x);
|
||||
int x0 = ifetchPos.x;
|
||||
int x1 = ifetchPos.x + 1;
|
||||
if (x1 == isize.x)
|
||||
x1 = 0;
|
||||
|
||||
float depth0 = texelFetch(ShadowMap, ivec2(x0, y), 0).x;
|
||||
float depth1 = texelFetch(ShadowMap, ivec2(x1, y), 0).x;
|
||||
return mix(step(dist2, depth0), step(dist2, depth1), t);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Check if light is in shadow using Percentage Closer Filtering (PCF)
|
||||
|
@ -168,6 +198,9 @@ float sampleShadowmap(vec2 dir, float v)
|
|||
#define PCF_FILTER_STEP_COUNT 3
|
||||
#define PCF_COUNT (PCF_FILTER_STEP_COUNT * 2 + 1)
|
||||
|
||||
// #define USE_LINEAR_SHADOW_FILTER
|
||||
#define USE_PCF_SHADOW_FILTER 1
|
||||
|
||||
float shadowmapAttenuation(vec4 lightpos, float shadowIndex)
|
||||
{
|
||||
if (shadowIndex >= 1024.0)
|
||||
|
@ -182,7 +215,11 @@ float shadowmapAttenuation(vec4 lightpos, float shadowIndex)
|
|||
|
||||
vec2 dir = ray / length;
|
||||
|
||||
ray -= dir * 2.0; // margin
|
||||
#if defined(USE_LINEAR_SHADOW_FILTER)
|
||||
ray -= dir * 6.0; // Shadow acne margin
|
||||
return sampleShadowmapLinear(ray, v);
|
||||
#elif defined(USE_PCF_SHADOW_FILTER)
|
||||
ray -= dir * 2.0; // Shadow acne margin
|
||||
dir = dir * min(length / 50.0, 1.0); // avoid sampling behind light
|
||||
|
||||
vec2 normal = vec2(-dir.y, dir.x);
|
||||
|
@ -194,6 +231,10 @@ float shadowmapAttenuation(vec4 lightpos, float shadowIndex)
|
|||
sum += sampleShadowmap(ray + normal * x - bias * abs(x), v);
|
||||
}
|
||||
return sum / PCF_COUNT;
|
||||
#else // nearest shadow filter
|
||||
ray -= dir * 6.0; // Shadow acne margin
|
||||
return sampleShadowmap(ray, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue