diff options
| author | 2016-05-10 23:00:40 -0400 | |
|---|---|---|
| committer | 2016-05-10 23:00:40 -0400 | |
| commit | 86ecbdfa4de5654fb1f3e998921af8db1d5373cf (patch) | |
| tree | a1fa859a3e2a8183eb7b3d367c41aa91a747b39f /src/video_core/rasterizer.cpp | |
| parent | Merge pull request #1774 from lioncash/warn (diff) | |
| parent | OpenGL: Implement W-Buffers and fix depth-mapping (diff) | |
| download | yuzu-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.cpp | 26 |
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); |