Pixel depth rounding: Floor with room for float error, store Z like clears

The fragment Z is the PSP's Z / 65536, and flat draws land exactly on an
integer Z. floor(z * 65535) put that Z - Z/65536 just above the boundary, so
float error (which differs with W) could drop it by one: Patlabor redraws a
HUD icon at the same depth with GEQUAL, and the second draw failed on
Vulkan. Floor Z + 0.01 instead, and store Z / 65535, as clears and the depth
clamp path do. Also fixes Heroes Phantasia #6485.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-08 16:16:24 +02:00
1 parent b4619757ad
commit f1a6232841
1 file changed
+4 -1
+4 -1
View File
@@ -1204,7 +1204,10 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu
if (fsDepthClamp) {
WRITE(p, " gl_FragDepth = clamp(floor(projZ), 0.0, 65535.0) / 65535.0;\n");
} else {
WRITE(p, " gl_FragDepth = floor(gl_FragCoord.z * 65535.0) / 65535.0;\n");
// gl_FragCoord.z is the PSP's Z / 65536. Flat draws land exactly on an integer Z, so floor with some
// room for float error, which differs with W (Patlabor's HUD redraws an icon with GEQUAL). Then store
// Z / 65535 like clears and the clamp path above.
WRITE(p, " gl_FragDepth = floor(gl_FragCoord.z * 65536.0 + 0.01) / 65535.0;\n");
}
} else if (fsDepthClamp) {
WRITE(p, " gl_FragDepth = clamp(projZ, 0.0, 65535.0) / 65535.0;\n");