Skip to content

Commit

Permalink
Merge pull request #16069 from unknownbrackets/depth-clamp
Browse files Browse the repository at this point in the history
GPU: Simplify depth clamped clip planes
  • Loading branch information
hrydgard authored Sep 21, 2022
2 parents 95ea045 + f8d29fd commit 3ff400e
Showing 1 changed file with 4 additions and 7 deletions.
11 changes: 4 additions & 7 deletions GPU/Common/VertexShaderGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1189,37 +1189,34 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
WRITE(p, " %sv_fogdepth = (viewPos.z + u_fogcoef.x) * u_fogcoef.y;\n", compat.vsOutPrefix);
}

if (clipClampedDepth || (vertexRangeCulling && !IsVRBuild())) {
WRITE(p, " vec3 projPos = outPos.xyz / outPos.w;\n");
}

if (clipClampedDepth) {
const char *clip0 = compat.shaderLanguage == HLSL_D3D11 ? ".x" : "[0]";
const char *clip1 = compat.shaderLanguage == HLSL_D3D11 ? ".y" : "[1]";
WRITE(p, " mediump float integerZ = projPos.z * u_depthRange.x + u_depthRange.y;\n");

// This should clip against minz, but only when it's above zero.
if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) {
// On OpenGL/GLES, these values account for the -1 -> 1 range.
WRITE(p, " if (u_depthRange.y - u_depthRange.x >= 1.0) {\n");
WRITE(p, " %sgl_ClipDistance%s = outPos.w + outPos.z;\n", compat.vsOutPrefix, clip0);
} else {
// Everywhere else, it's 0 -> 1, simpler.
WRITE(p, " if (u_depthRange.y >= 1.0) {\n");
WRITE(p, " %sgl_ClipDistance%s = outPos.z;\n", compat.vsOutPrefix, clip0);
}
WRITE(p, " %sgl_ClipDistance%s = integerZ * outPos.w;\n", compat.vsOutPrefix, clip0);
WRITE(p, " } else {\n");
WRITE(p, " %sgl_ClipDistance%s = 0.0;\n", compat.vsOutPrefix, clip0);
WRITE(p, " }\n");

// This is similar, but for maxz when it's below 65535.0. -1/0 don't matter here.
WRITE(p, " if (u_depthRange.x + u_depthRange.y <= 65534.0) {\n");
WRITE(p, " %sgl_ClipDistance%s = (65535.0 - integerZ) * outPos.w;\n", compat.vsOutPrefix, clip1);
WRITE(p, " %sgl_ClipDistance%s = outPos.w - outPos.z;\n", compat.vsOutPrefix, clip1);
WRITE(p, " } else {\n");
WRITE(p, " %sgl_ClipDistance%s = 0.0;\n", compat.vsOutPrefix, clip1);
WRITE(p, " }\n");
}

if (vertexRangeCulling && !IsVRBuild()) {
WRITE(p, " vec3 projPos = outPos.xyz / outPos.w;\n");
WRITE(p, " float projZ = (projPos.z - u_depthRange.z) * u_depthRange.w;\n");
// Vertex range culling doesn't happen when Z clips, note sign of w is important.
WRITE(p, " if (u_cullRangeMin.w <= 0.0 || projZ * outPos.w > -outPos.w) {\n");
Expand Down

0 comments on commit 3ff400e

Please sign in to comment.