Skip to content

Commit

Permalink
improved shadow volume for mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
IanLilleyT committed Aug 23, 2020
1 parent fa2edd6 commit b9fed22
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
28 changes: 24 additions & 4 deletions Source/Shaders/Builtin/Functions/depthClamp.glsl
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
// emulated noperspective
#ifndef LOG_DEPTH
#if defined(GL_EXT_frag_depth) && !defined(LOG_DEPTH)
varying float v_WindowZ;
#endif

/**
* Clamps a vertex to the near and far planes.
* 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:
* https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_depth_clamp.txt.
*
* When GL_EXT_frag_depth is available we emulate GL_DEPTH_CLAMP by ensuring
* no geometry gets clipped by setting the clip space z value to 0.0 and then
* sending the unaltered screen space z value (using emulated noperspective
* interpolation) to the frag shader where it is clamped to [0,1] and then
* written with gl_FragDepth (see czm_writeDepthClamp). This technique is based on:
* 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.
* The approach is to clamp the z value to the far plane, which closes the
* shadow volume but also distorts the geometry, so there can still be artifacts
* on frustum seams.
*
* @name czm_depthClamp
* @glslFunction
*
* @param {vec4} coords The vertex in clip coordinates.
* @returns {vec4} The vertex clipped to the near and far planes.
* @returns {vec4} The modified vertex.
*
* @example
* gl_Position = czm_depthClamp(czm_modelViewProjection * vec4(position, 1.0));
Expand All @@ -20,8 +36,12 @@ varying float v_WindowZ;
vec4 czm_depthClamp(vec4 coords)
{
#ifndef LOG_DEPTH
#ifdef GL_EXT_frag_depth
v_WindowZ = (0.5 * (coords.z / coords.w) + 0.5) * coords.w;
coords.z = clamp(coords.z, -coords.w, +coords.w);
coords.z = 0.0;
#else
coords.z = min(coords.z, coords.w);
#endif
#endif
return coords;
}
6 changes: 4 additions & 2 deletions Source/Shaders/Builtin/Functions/writeDepthClamp.glsl
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// emulated noperspective
#ifndef LOG_DEPTH
#if defined(GL_EXT_frag_depth) && !defined(LOG_DEPTH)
varying float v_WindowZ;
#endif

/**
* Clamps a vertex to the far plane by writing the fragments depth.
* Emulates GL_DEPTH_CLAMP. Clamps a fragment to the near and far plane
* by writing the fragment's depth. See czm_depthClamp for more details.
* <p>
* The shader must enable the GL_EXT_frag_depth extension.
* </p>
Expand Down

0 comments on commit b9fed22

Please sign in to comment.