mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-29 21:45:32 +00:00
Add normal-offset shadow mapping to remove shadow acne (flicker)
This commit is contained in:
parent
8482236a82
commit
556c9a3382
6 changed files with 41 additions and 6 deletions
|
@ -125,6 +125,10 @@ namespace SceneUtil
|
|||
else
|
||||
definesWithShadows["perspectiveShadowMaps"] = "0";
|
||||
|
||||
definesWithShadows["disableNormalOffsetShadows"] = Settings::Manager::getFloat("normal offset distance", "Shadows") == 0.0 ? "1" : "0";
|
||||
|
||||
definesWithShadows["shadowNormalOffset"] = std::to_string(Settings::Manager::getFloat("normal offset distance", "Shadows"));
|
||||
|
||||
return definesWithShadows;
|
||||
}
|
||||
|
||||
|
@ -140,6 +144,10 @@ namespace SceneUtil
|
|||
|
||||
definesWithShadows["perspectiveShadowMaps"] = "0";
|
||||
|
||||
definesWithShadows["enableNormalOffsetShadows"] = "0";
|
||||
|
||||
definesWithShadows["shadowNormalOffset"] = "0.0";
|
||||
|
||||
return definesWithShadows;
|
||||
}
|
||||
void ShadowManager::enableIndoorMode()
|
||||
|
|
|
@ -669,6 +669,8 @@ minimum lispsm near far ratio = 0.25
|
|||
polygon offset factor = 1.1
|
||||
# Used as the units parameter for the polygon offset used for shadow map rendering. Higher values reduce shadow flicker, but risk increasing Peter Panning. See https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glPolygonOffset.xhtml for details.
|
||||
polygon offset units = 4.0
|
||||
# How far along the surface normal to project shadow coordinates. Higher values significantly reduce shadow flicker, usually with a lower increase of Peter Panning than the Polygon Offset settings. This value is in in-game units, so 1.0 is roughly 1.4 cm.
|
||||
normal offset distance = 1.0
|
||||
# Excludes theoretically unnecessary faces from shadow maps, slightly increasing performance. In practice, Peter Panning can be much less visible with these faces included, so if you have high polygon offset values, disabling this may help minimise the side effects.
|
||||
use front face culling = true
|
||||
# Allow actors to cast shadows. Potentially decreases performance.
|
||||
|
|
|
@ -103,5 +103,5 @@ void main(void)
|
|||
passViewPos = viewPos.xyz;
|
||||
passNormal = gl_Normal.xyz;
|
||||
|
||||
setupShadowCoords(viewPos);
|
||||
setupShadowCoords(viewPos, viewNormal);
|
||||
}
|
||||
|
|
|
@ -10,20 +10,44 @@
|
|||
varying vec4 shadowRegionCoords@shadow_texture_unit_index;
|
||||
#endif
|
||||
@endforeach
|
||||
|
||||
// Enabling this may reduce peter panning. Probably unnecessary.
|
||||
const bool onlyNormalOffsetUV = false;
|
||||
#endif // SHADOWS
|
||||
|
||||
void setupShadowCoords(vec4 viewPos)
|
||||
void setupShadowCoords(vec4 viewPos, vec3 viewNormal)
|
||||
{
|
||||
#if SHADOWS
|
||||
// This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner.
|
||||
mat4 eyePlaneMat;
|
||||
vec4 shadowOffset;
|
||||
@foreach shadow_texture_unit_index @shadow_texture_unit_list
|
||||
eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneT[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneR[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneQ[shadowTextureUnit@shadow_texture_unit_index]);
|
||||
shadowSpaceCoords@shadow_texture_unit_index = viewPos * eyePlaneMat;
|
||||
|
||||
#if @perspectiveShadowMaps
|
||||
shadowRegionCoords@shadow_texture_unit_index = validRegionMatrix@shadow_texture_unit_index * viewPos;
|
||||
#endif
|
||||
|
||||
#if @disableNormalOffsetShadows
|
||||
shadowSpaceCoords@shadow_texture_unit_index = viewPos * eyePlaneMat;
|
||||
#else
|
||||
shadowOffset = vec4(viewNormal * @shadowNormalOffset, 0.0);
|
||||
|
||||
if (onlyNormalOffsetUV)
|
||||
{
|
||||
shadowSpaceCoords@shadow_texture_unit_index = viewPos * eyePlaneMat;
|
||||
|
||||
vec4 lightSpaceXY = viewPos + shadowOffset;
|
||||
lightSpaceXY = lightSpaceXY * eyePlaneMat;
|
||||
|
||||
shadowSpaceCoords@shadow_texture_unit_index.xy = lightSpaceXY.xy;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec4 offsetViewPosition = viewPos + shadowOffset;
|
||||
shadowSpaceCoords@shadow_texture_unit_index = offsetViewPosition * eyePlaneMat;
|
||||
}
|
||||
#endif
|
||||
@endforeach
|
||||
#endif // SHADOWS
|
||||
}
|
|
@ -25,9 +25,10 @@ void main(void)
|
|||
|
||||
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
|
||||
gl_ClipVertex = viewPos;
|
||||
|
||||
vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz);
|
||||
|
||||
#if !PER_PIXEL_LIGHTING
|
||||
vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz);
|
||||
lighting = doLighting(viewPos.xyz, viewNormal, gl_Color, shadowDiffuseLighting);
|
||||
#else
|
||||
passColor = gl_Color;
|
||||
|
@ -37,5 +38,5 @@ void main(void)
|
|||
|
||||
uv = gl_MultiTexCoord0.xy;
|
||||
|
||||
setupShadowCoords(viewPos);
|
||||
setupShadowCoords(viewPos, viewNormal);
|
||||
}
|
||||
|
|
|
@ -22,5 +22,5 @@ void main(void)
|
|||
|
||||
depthPassthrough = gl_Position.z;
|
||||
|
||||
setupShadowCoords(gl_ModelViewMatrix * gl_Vertex);
|
||||
setupShadowCoords(gl_ModelViewMatrix * gl_Vertex, normalize((gl_NormalMatrix * gl_Normal).xyz));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue