summaryrefslogtreecommitdiff
path: root/src/video_core/rasterizer.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2016-05-10 23:00:40 -0400
committerGravatar bunnei2016-05-10 23:00:40 -0400
commit86ecbdfa4de5654fb1f3e998921af8db1d5373cf (patch)
treea1fa859a3e2a8183eb7b3d367c41aa91a747b39f /src/video_core/rasterizer.cpp
parentMerge pull request #1774 from lioncash/warn (diff)
parentOpenGL: Implement W-Buffers and fix depth-mapping (diff)
downloadyuzu-86ecbdfa4de5654fb1f3e998921af8db1d5373cf.tar.gz
yuzu-86ecbdfa4de5654fb1f3e998921af8db1d5373cf.tar.xz
yuzu-86ecbdfa4de5654fb1f3e998921af8db1d5373cf.zip
Merge pull request #1621 from JayFoxRox/w-buffer
Implement W-buffer and fix depth-mapping
Diffstat (limited to 'src/video_core/rasterizer.cpp')
-rw-r--r--src/video_core/rasterizer.cpp26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index df67b9081..80cad9056 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -862,10 +862,30 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0,
862 } 862 }
863 } 863 }
864 864
865 // interpolated_z = z / w
866 float interpolated_z_over_w = (v0.screenpos[2].ToFloat32() * w0 +
867 v1.screenpos[2].ToFloat32() * w1 +
868 v2.screenpos[2].ToFloat32() * w2) / wsum;
869
870 // Not fully accurate. About 3 bits in precision are missing.
871 // Z-Buffer (z / w * scale + offset)
872 float depth_scale = float24::FromRaw(regs.viewport_depth_range).ToFloat32();
873 float depth_offset = float24::FromRaw(regs.viewport_depth_near_plane).ToFloat32();
874 float depth = interpolated_z_over_w * depth_scale + depth_offset;
875
876 // Potentially switch to W-Buffer
877 if (regs.depthmap_enable == Pica::Regs::DepthBuffering::WBuffering) {
878
879 // W-Buffer (z * scale + w * offset = (z / w * scale + offset) * w)
880 depth *= interpolated_w_inverse.ToFloat32() * wsum;
881 }
882
883 // Clamp the result
884 depth = MathUtil::Clamp(depth, 0.0f, 1.0f);
885
886 // Convert float to integer
865 unsigned num_bits = Regs::DepthBitsPerPixel(regs.framebuffer.depth_format); 887 unsigned num_bits = Regs::DepthBitsPerPixel(regs.framebuffer.depth_format);
866 u32 z = (u32)((v0.screenpos[2].ToFloat32() * w0 + 888 u32 z = (u32)(depth * ((1 << num_bits) - 1));
867 v1.screenpos[2].ToFloat32() * w1 +
868 v2.screenpos[2].ToFloat32() * w2) * ((1 << num_bits) - 1) / wsum);
869 889
870 if (output_merger.depth_test_enable) { 890 if (output_merger.depth_test_enable) {
871 u32 ref_z = GetDepth(x >> 4, y >> 4); 891 u32 ref_z = GetDepth(x >> 4, y >> 4);