From d81a75c867e2e416e38ad9584b25b67b68de1b52 Mon Sep 17 00:00:00 2001 From: rogerman Date: Sat, 17 Nov 2018 23:20:59 -0800 Subject: [PATCH] SoftRasterizer / OpenGL Renderer: Drop less bits in the depth calculation, making for smoother depth transitions. For certain games, this may allow for better distance rendering, especially at the higher resolutions. (Related to commit c9025e8.) - SoftRasterizer may now drop at most one LSB, down from dropping 9 LSBs. - OpenGL will now drop only 2 LSBs, down from 9 LSBs. In this case, dropping 2 LSBs was specifically chosen to ensure that the Dragon Quest IV overworld map continues to work. - If this change makes the depth inaccuracy too much worse than before, then we may have to make these particular depth calculations optional in the future. This will need additional testing. --- desmume/src/OGLRender.cpp | 2 +- desmume/src/OGLRender_3_2.cpp | 2 +- desmume/src/rasterize.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index a8e48584b..e3683feb0 100755 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -336,7 +336,7 @@ static const char *GeometryFragShader_100 = {"\ float vertW = (vtxPosition.w == 0.0) ? 0.00000001 : vtxPosition.w;\n\ float depthOffset = (polyDepthOffsetMode == 0) ? 0.0 : ((polyDepthOffsetMode == 1) ? -DEPTH_EQUALS_TEST_TOLERANCE : DEPTH_EQUALS_TEST_TOLERANCE);\n\ // hack: when using z-depth, drop some LSBs so that the overworld map in Dragon Quest IV shows up correctly\n\ - float newFragDepthValue = (stateUseWDepth) ? clamp( ( floor(vtxPosition.w * 4096.0) + depthOffset ) / 16777215.0, 0.0, 1.0 ) : clamp( ( (floor(clamp(((vtxPosition.z/vertW) * 0.5 + 0.5), 0.0, 1.0) * 32767.0) * 512.0) + depthOffset ) / 16777215.0, 0.0, 1.0 );\n\ + float newFragDepthValue = (stateUseWDepth) ? clamp( ( (vtxPosition.w * 4096.0) + depthOffset ) / 16777215.0, 0.0, 1.0 ) : clamp( ( (floor(((vtxPosition.z/vertW) * 0.5 + 0.5) * 4194303.0) * 4.0) + depthOffset ) / 16777215.0, 0.0, 1.0 );\n\ \n\ if ((polyMode != 3) || polyDrawShadow)\n\ {\n\ diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index b1a6d8fbf..1f8688d94 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -207,7 +207,7 @@ static const char *GeometryFragShader_150 = {"\ float vertW = (vtxPosition.w == 0.0) ? 0.00000001 : vtxPosition.w;\n\ float depthOffset = (polyDepthOffsetMode == 0) ? 0.0 : ((polyDepthOffsetMode == 1) ? -DEPTH_EQUALS_TEST_TOLERANCE : DEPTH_EQUALS_TEST_TOLERANCE);\n\ // hack: when using z-depth, drop some LSBs so that the overworld map in Dragon Quest IV shows up correctly\n\ - float newFragDepthValue = (state.useWDepth) ? clamp( ( floor(vtxPosition.w * 4096.0) + depthOffset ) / 16777215.0, 0.0, 1.0 ) : clamp( ( (floor(clamp(((vtxPosition.z/vertW) * 0.5 + 0.5), 0.0, 1.0) * 32767.0) * 512.0) + depthOffset ) / 16777215.0, 0.0, 1.0 );\n\ + float newFragDepthValue = (state.useWDepth) ? clamp( ( (vtxPosition.w * 4096.0) + depthOffset ) / 16777215.0, 0.0, 1.0 ) : clamp( ( (floor(((vtxPosition.z/vertW) * 0.5 + 0.5) * 4194303.0) * 4.0) + depthOffset ) / 16777215.0, 0.0, 1.0 );\n\ \n\ if ((polyMode != 3u) || polyDrawShadow)\n\ {\n\ diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index 330c15586..f59923a91 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -517,7 +517,7 @@ FORCEINLINE void RasterizerUnit::_pixel(const POLYGON_ATTR polyAttr, c // When using z-depth, be sure to test against the following test cases: // - The drawing of the overworld map in Dragon Quest IV // - The drawing of all units on the map in Advance Wars: Days of Ruin - const u32 newDepth = (gfx3d.renderState.wbuffer) ? u32floor(4096*w) : (u32floor(z*0x7FFF) << 9); + const u32 newDepth = (gfx3d.renderState.wbuffer) ? u32floor(w * 4096.0f) : u32floor(z * 16777215.0f); // run the depth test bool depthFail = false;