From f1a6232841a52fa4cefbe17abcd88dba2200ecb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 8 Oct 2026 14:10:20 +0200 Subject: [PATCH] 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 --- GPU/Common/FragmentShaderGenerator.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/GPU/Common/FragmentShaderGenerator.cpp b/GPU/Common/FragmentShaderGenerator.cpp index 6e485fbf1a..01bb2e85f1 100644 --- a/GPU/Common/FragmentShaderGenerator.cpp +++ b/GPU/Common/FragmentShaderGenerator.cpp @@ -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");