Improve shadow quality and performance in gl33
If CONFIG_QUALITY_SHADOWS is defined (which it always is) then the fragment shader code that samples the shadow map will take five samples in a cross shape around the point to be sampled, to apply antialiasing. Currently, the offset of these samples is hardcoded to 0.00025× the shadow map resolution. This is very inconsistent: if the shadow map resolution is 128×128, then these samples are 0.032 texels apart, which is a waste of four texture samples, and essentially means that no antialiasing is applied. If the shadow map resolution is 8192×8192, then these samples are 2.048 texels apart, which causes visual artefacts around shadow edges, instead of giving smoother shadows. The correct thing to do is to always sample exactly one texel away from the original position. This is easy in GLSL 3.30, as it includes a textureOffset function which offsets a texture fetch by an exact number of texels. This is faster than manually calculating an offset ourselves, it fixes visual artefacts at high resolutions, and it properly applies antialiasing at low resolutions.1008-fix
parent
fdf67b8217
commit
0d6fffd91f
|
@ -96,19 +96,15 @@ void main()
|
|||
|
||||
if (uni_ShadowTextureEnabled)
|
||||
{
|
||||
float value = texture(uni_ShadowTexture, data.ShadowCoord.xyz);
|
||||
#ifdef CONFIG_QUALITY_SHADOWS
|
||||
float offset = 0.00025f;
|
||||
|
||||
float value = (1.0f / 5.0f) * (texture(uni_ShadowTexture, data.ShadowCoord.xyz)
|
||||
+ texture(uni_ShadowTexture, data.ShadowCoord.xyz + vec3( offset, 0.0f, 0.0f))
|
||||
+ texture(uni_ShadowTexture, data.ShadowCoord.xyz + vec3(-offset, 0.0f, 0.0f))
|
||||
+ texture(uni_ShadowTexture, data.ShadowCoord.xyz + vec3( 0.0f, offset, 0.0f))
|
||||
+ texture(uni_ShadowTexture, data.ShadowCoord.xyz + vec3( 0.0f, -offset, 0.0f)));
|
||||
|
||||
shadow = mix(uni_ShadowColor, 1.0f, value);
|
||||
#else
|
||||
shadow = mix(uni_ShadowColor, 1.0f, texture(uni_ShadowTexture, data.ShadowCoord.xyz));
|
||||
value += textureOffset(uni_ShadowTexture, data.ShadowCoord.xyz, ivec2( 1, 0))
|
||||
+ textureOffset(uni_ShadowTexture, data.ShadowCoord.xyz, ivec2(-1, 0))
|
||||
+ textureOffset(uni_ShadowTexture, data.ShadowCoord.xyz, ivec2( 0, 1))
|
||||
+ textureOffset(uni_ShadowTexture, data.ShadowCoord.xyz, ivec2( 0,-1));
|
||||
value = value * (1.0f / 5.0f);
|
||||
#endif
|
||||
shadow = mix(uni_ShadowColor, 1.0f, value);
|
||||
}
|
||||
|
||||
vec4 result = uni_AmbientColor * ambient
|
||||
|
|
Loading…
Reference in New Issue