From cdf5e4b2b26323fe68d828c0dbccf05b2661768f Mon Sep 17 00:00:00 2001 From: Ian Curtis Date: Fri, 17 Nov 2023 16:07:20 +0000 Subject: [PATCH] Fix transparency depth testing The two transparency layers, might not be separate layers at all. We believe the hardware is writing each layer to every other pixel (stipple alpha), then using an anti-aliasing filter to effectively blend the pixels. Because the pixels don't overlap they don't depth test against each other. We are using separate layers to emulate this, so the depth buffer must be saved and restored between the layers. --- Src/Graphics/New3D/New3D.cpp | 2 ++ Src/Graphics/New3D/R3DFrameBuffers.cpp | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Src/Graphics/New3D/New3D.cpp b/Src/Graphics/New3D/New3D.cpp index f18d385..88e3bc3 100644 --- a/Src/Graphics/New3D/New3D.cpp +++ b/Src/Graphics/New3D/New3D.cpp @@ -425,10 +425,12 @@ void CNew3D::RenderFrame(void) m_r3dShader.DiscardAlpha(false); + m_r3dFrameBuffers.StoreDepth(); m_r3dShader.SetLayer(Layer::trans1); m_r3dFrameBuffers.SetFBO(Layer::trans1); RenderScene(pri, renderOverlay, Layer::trans1); + m_r3dFrameBuffers.RestoreDepth(); m_r3dShader.SetLayer(Layer::trans2); m_r3dFrameBuffers.SetFBO(Layer::trans2); RenderScene(pri, renderOverlay, Layer::trans2); diff --git a/Src/Graphics/New3D/R3DFrameBuffers.cpp b/Src/Graphics/New3D/R3DFrameBuffers.cpp index 7461b01..5f145a2 100644 --- a/Src/Graphics/New3D/R3DFrameBuffers.cpp +++ b/Src/Graphics/New3D/R3DFrameBuffers.cpp @@ -277,7 +277,10 @@ void R3DFrameBuffers::AllocShaderTrans() // if both transparency layers overlap, the result is opaque if (colTrans1.a * colTrans2.a > 0.0) { - vec3 mixCol = mix(colTrans1.rgb, colTrans2.rgb, (colTrans2.a + (1.0 - colTrans1.a)) / 2.0); + + // are the two lines functionally identical? Need to check. + //vec3 mixCol = mix(colTrans1.rgb, colTrans2.rgb, (colTrans2.a + (1.0 - colTrans1.a)) / 2.0); + vec3 mixCol = (((colTrans1.rgb * colTrans1.a) + (colTrans2.rgb * (1.0-colTrans1.a))) + ((colTrans2.rgb * colTrans2.a) + (colTrans1 .rgb * (1.0-colTrans2.a)))) / 2.0; fragColor = vec4(mixCol, 1.0); } else if (colTrans1.a > 0.0) {