Fixed shadow volume regression for mobile #9108
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #8953
#8854 clamped vertices to the near plane in order to create a watertight shadow volume. While this happened to work well for orthographic mode, and worked sometimes on desktop (curiously, only when ANGLE was enabled), it broke down for mobile, and was flawed to begin with. This is because the way we do shadow volumes doesn't actually require the front of the volume to be closed, just the back.
Ultimately we want a solution that emulates
GL_DEPTH_CLAMP
, which is not available in WebGL 1 or 2.GL_DEPTH_CLAMP
clamps geometry that is outside the near and far planes, capping the shadow volume. More information here.We emulate
GL_DEPTH_CLAMP
by ensuring no geometry gets clipped by setting the clip spacez
value to0.0
and then sending the unaltered screen spacez
value (using emulatednoperspective
interpolation) to the frag shader where it is clamped to[0,1]
and then written withgl_FragDepth
. This is the solution whenGL_EXT_frag_depth
is available and works for both perspective and orthographic. It is based off of https://stackoverflow.com/questions/5960757/how-to-emulate-gl-depth-clamp-nv.When
GL_EXT_frag_depth
is not available, which is the case on some mobile devices, we must attempt to fix this only in the vertex shader. Our approach is to clamp thez
value to the far plane, which closes the shadow volume but also distorts the geometry, so there can still be artifacts on frustum seams but it won't be as severe as the code in #8854 which also clamps the near plane unnecessarily.Before:
After:
Sandcastle
Here are some examples of frustum seam artifacts that could not be fixed in this PR when
GL_EXT_frag_depth
is not available. These artifacts have existed since shadow volumes were first implemented:Sandcastle for testing more options
@lilleyse and I worked on this fix together so someone else should review. @kring?
CC @OmarShehata