From 5cf2d774f3406e98f9cac6972ff18ed473886468 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 18 Nov 2017 13:02:10 +0300 Subject: [PATCH] fp32 precision on GPUs is embarassing - Division seems to suffer from drift easily on GPUs due to limited precision --- rpcs3/Emu/RSX/GL/GLVertexProgram.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index e3e00c8412..46019ccfdd 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -306,13 +306,15 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS) //It is therefore critical that this step is done post-transform and the result re-scaled by w //SEE Naruto: UNS - OS << " float ndc_z = gl_Position.z / gl_Position.w;\n"; - OS << " ndc_z = (ndc_z * 2.) - 1.;\n"; - OS << " gl_Position.z = ndc_z * gl_Position.w;\n"; + //NOTE: On GPUs, poor fp32 precision means dividing z by w, then multiplying by w again gives slightly incorrect results + //This equation is simplified algebraically to an addition and subreaction which gives more accurate results (Fixes flickering skybox in Dark Souls 2) + //OS << " float ndc_z = gl_Position.z / gl_Position.w;\n"; + //OS << " ndc_z = (ndc_z * 2.) - 1.;\n"; + //OS << " gl_Position.z = ndc_z * gl_Position.w;\n"; + OS << " gl_Position.z = (gl_Position.z + gl_Position.z) - gl_Position.w;\n"; OS << "}\n"; } - void GLVertexDecompilerThread::Task() { m_shader = Decompile();