diff options
| author | bunnei <bunneidev@gmail.com> | 2016-05-10 23:00:40 -0400 |
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2016-05-10 23:00:40 -0400 |
| commit | 86ecbdfa4de5654fb1f3e998921af8db1d5373cf (patch) | |
| tree | a1fa859a3e2a8183eb7b3d367c41aa91a747b39f /src/video_core/rasterizer.cpp | |
| parent | feecc76333c56e42b9de590bef14e9e9872fbc5d (diff) | |
| parent | fc9cc21024bff71d98e0106c9d0fd0476ab3c17e (diff) | |
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, } } + // interpolated_z = z / w + float interpolated_z_over_w = (v0.screenpos[2].ToFloat32() * w0 + + v1.screenpos[2].ToFloat32() * w1 + + v2.screenpos[2].ToFloat32() * w2) / wsum; + + // Not fully accurate. About 3 bits in precision are missing. + // Z-Buffer (z / w * scale + offset) + float depth_scale = float24::FromRaw(regs.viewport_depth_range).ToFloat32(); + float depth_offset = float24::FromRaw(regs.viewport_depth_near_plane).ToFloat32(); + float depth = interpolated_z_over_w * depth_scale + depth_offset; + + // Potentially switch to W-Buffer + if (regs.depthmap_enable == Pica::Regs::DepthBuffering::WBuffering) { + + // W-Buffer (z * scale + w * offset = (z / w * scale + offset) * w) + depth *= interpolated_w_inverse.ToFloat32() * wsum; + } + + // Clamp the result + depth = MathUtil::Clamp(depth, 0.0f, 1.0f); + + // Convert float to integer unsigned num_bits = Regs::DepthBitsPerPixel(regs.framebuffer.depth_format); - u32 z = (u32)((v0.screenpos[2].ToFloat32() * w0 + - v1.screenpos[2].ToFloat32() * w1 + - v2.screenpos[2].ToFloat32() * w2) * ((1 << num_bits) - 1) / wsum); + u32 z = (u32)(depth * ((1 << num_bits) - 1)); if (output_merger.depth_test_enable) { u32 ref_z = GetDepth(x >> 4, y >> 4); |
