diff --git a/Source/Core/VideoCommon/ConstantManager.h b/Source/Core/VideoCommon/ConstantManager.h index b8c65aaefb..f8b4616332 100644 --- a/Source/Core/VideoCommon/ConstantManager.h +++ b/Source/Core/VideoCommon/ConstantManager.h @@ -86,7 +86,7 @@ struct alignas(16) VertexShaderConstants std::array transformmatrices; std::array normalmatrices; std::array posttransformmatrices; - float4 pixelcentercorrection; + float4 pixelpositioncorrection; std::array viewport; // .xy std::array pad2; // .zw diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h index 48f3d3d9bc..9ca611984d 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/ShaderGenCommon.h @@ -283,7 +283,7 @@ void WriteSwitch(ShaderCode& out, APIType ApiType, std::string_view variable, #define I_TRANSFORMMATRICES "ctrmtx" #define I_NORMALMATRICES "cnmtx" #define I_POSTTRANSFORMMATRICES "cpostmtx" -#define I_PIXELCENTERCORRECTION "cpixelcenter" +#define I_PIXELPOSITIONCORRECTION "cpixelposition" #define I_VIEWPORT_SIZE "cviewport" #define I_CACHED_TANGENT "ctangent" #define I_CACHED_BINORMAL "cbinormal" @@ -305,7 +305,7 @@ static const char s_shader_uniforms[] = "\tuint components;\n" "\tfloat4 " I_TRANSFORMMATRICES "[64];\n" "\tfloat4 " I_NORMALMATRICES "[32];\n" "\tfloat4 " I_POSTTRANSFORMMATRICES "[64];\n" - "\tfloat4 " I_PIXELCENTERCORRECTION ";\n" + "\tfloat4 " I_PIXELPOSITIONCORRECTION ";\n" "\tfloat2 " I_VIEWPORT_SIZE ";\n" "\tuint4 xfmem_pack1[8];\n" "\tfloat4 " I_CACHED_TANGENT ";\n" diff --git a/Source/Core/VideoCommon/UberShaderVertex.cpp b/Source/Core/VideoCommon/UberShaderVertex.cpp index eceda62e48..89a34bc254 100644 --- a/Source/Core/VideoCommon/UberShaderVertex.cpp +++ b/Source/Core/VideoCommon/UberShaderVertex.cpp @@ -438,8 +438,8 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{ // divide, because some games will use a depth range larger than what is allowed by the // graphics API. These large depth ranges will still be clipped to the 0..1 range, so these // games effectively add a depth bias to the values written to the depth buffer. - out.Write("o.pos.z = o.pos.w * " I_PIXELCENTERCORRECTION ".w - " - "o.pos.z * " I_PIXELCENTERCORRECTION ".z;\n"); + out.Write("o.pos.z = o.pos.w * " I_PIXELPOSITIONCORRECTION ".w - " + "o.pos.z * " I_PIXELPOSITIONCORRECTION ".z;\n"); if (!host_config.backend_clip_control) { @@ -451,15 +451,7 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{ // Correct for negative viewports by mirroring all vertices. We need to negate the height here, // since the viewport height is already negated by the render backend. - out.Write("o.pos.xy *= sign(" I_PIXELCENTERCORRECTION ".xy * float2(1.0, -1.0));\n"); - - // The console GPU places the pixel center at 7/12 in screen space unless - // antialiasing is enabled, while D3D and OpenGL place it at 0.5. This results - // in some primitives being placed one pixel too far to the bottom-right, - // which in turn can be critical if it happens for clear quads. - // Hence, we compensate for this pixel center difference so that primitives - // get rasterized correctly. - out.Write("o.pos.xy = o.pos.xy - o.pos.w * " I_PIXELCENTERCORRECTION ".xy;\n"); + out.Write("o.pos.xy *= sign(" I_PIXELPOSITIONCORRECTION ".xy * float2(1.0, -1.0));\n"); if (vertex_rounding) { diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index 9f854f2d9e..d8926bd036 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -624,8 +624,8 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho // divide, because some games will use a depth range larger than what is allowed by the // graphics API. These large depth ranges will still be clipped to the 0..1 range, so these // games effectively add a depth bias to the values written to the depth buffer. - out.Write("o.pos.z = o.pos.w * " I_PIXELCENTERCORRECTION ".w - " - "o.pos.z * " I_PIXELCENTERCORRECTION ".z;\n"); + out.Write("o.pos.z = o.pos.w * " I_PIXELPOSITIONCORRECTION ".w - " + "o.pos.z * " I_PIXELPOSITIONCORRECTION ".z;\n"); if (!host_config.backend_clip_control) { @@ -637,15 +637,7 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho // Correct for negative viewports by mirroring all vertices. We need to negate the height here, // since the viewport height is already negated by the render backend. - out.Write("o.pos.xy *= sign(" I_PIXELCENTERCORRECTION ".xy * float2(1.0, -1.0));\n"); - - // The console GPU places the pixel center at 7/12 in screen space unless - // antialiasing is enabled, while D3D and OpenGL place it at 0.5. This results - // in some primitives being placed one pixel too far to the bottom-right, - // which in turn can be critical if it happens for clear quads. - // Hence, we compensate for this pixel center difference so that primitives - // get rasterized correctly. - out.Write("o.pos.xy = o.pos.xy - o.pos.w * " I_PIXELCENTERCORRECTION ".xy;\n"); + out.Write("o.pos.xy *= sign(" I_PIXELPOSITIONCORRECTION ".xy * float2(1.0, -1.0));\n"); if (vertex_rounding) { diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index 38e7cefe18..ca106760fb 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -335,27 +335,14 @@ void VertexShaderManager::SetConstants(const std::vector& textures, { xf_state_manager.ResetViewportChange(); - // The console GPU places the pixel center at 7/12 unless antialiasing - // is enabled, while D3D and OpenGL place it at 0.5. See the comment - // in VertexShaderGen.cpp for details. // NOTE: If we ever emulate antialiasing, the sample locations set by // BP registers 0x01-0x04 need to be considered here. - const float pixel_center_correction = 7.0f / 12.0f - 0.5f; - const bool bUseVertexRounding = g_ActiveConfig.UseVertexRounding(); - const float viewport_width = bUseVertexRounding ? - (2.f * xfmem.viewport.wd) : - g_framebuffer_manager->EFBToScaledXf(2.f * xfmem.viewport.wd); - const float viewport_height = bUseVertexRounding ? - (2.f * xfmem.viewport.ht) : - g_framebuffer_manager->EFBToScaledXf(2.f * xfmem.viewport.ht); - const float pixel_size_x = 2.f / viewport_width; - const float pixel_size_y = 2.f / viewport_height; - constants.pixelcentercorrection[0] = pixel_center_correction * pixel_size_x; - constants.pixelcentercorrection[1] = pixel_center_correction * pixel_size_y; + constants.pixelpositioncorrection[0] = xfmem.viewport.wd >= 0 ? 1.0f : -1.0f; + constants.pixelpositioncorrection[1] = xfmem.viewport.ht >= 0 ? 1.0f : -1.0f; // By default we don't change the depth value at all in the vertex shader. - constants.pixelcentercorrection[2] = 1.0f; - constants.pixelcentercorrection[3] = 0.0f; + constants.pixelpositioncorrection[2] = 1.0f; + constants.pixelpositioncorrection[3] = 0.0f; constants.viewport[0] = (2.f * xfmem.viewport.wd); constants.viewport[1] = (2.f * xfmem.viewport.ht); @@ -368,19 +355,19 @@ void VertexShaderManager::SetConstants(const std::vector& textures, { // Sometimes the console also tries to use the reversed-Z trick. We can only do // that with the expected accuracy if the backend can reverse the depth range. - constants.pixelcentercorrection[2] = fabs(xfmem.viewport.zRange) / 16777215.0f; + constants.pixelpositioncorrection[2] = fabs(xfmem.viewport.zRange) / 16777215.0f; if (xfmem.viewport.zRange < 0.0f) - constants.pixelcentercorrection[3] = xfmem.viewport.farZ / 16777215.0f; + constants.pixelpositioncorrection[3] = xfmem.viewport.farZ / 16777215.0f; else - constants.pixelcentercorrection[3] = 1.0f - xfmem.viewport.farZ / 16777215.0f; + constants.pixelpositioncorrection[3] = 1.0f - xfmem.viewport.farZ / 16777215.0f; } else { // For backends that don't support reversing the depth range we can still render // cases where the console uses the reversed-Z trick. But we simply can't provide // the expected accuracy, which might result in z-fighting. - constants.pixelcentercorrection[2] = xfmem.viewport.zRange / 16777215.0f; - constants.pixelcentercorrection[3] = 1.0f - xfmem.viewport.farZ / 16777215.0f; + constants.pixelpositioncorrection[2] = xfmem.viewport.zRange / 16777215.0f; + constants.pixelpositioncorrection[3] = 1.0f - xfmem.viewport.farZ / 16777215.0f; } }