From cf390655114d4e70f8bd90f5789fb5150bfe3435 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 10 Jan 2026 10:52:48 +0100 Subject: [PATCH] OpenGL: don't use alpha test for GLSL materials (#16832) This fixes crack for transparent textures on legacy GL (overlay was visible even if base was transparent), because our shader code assumed that transparent pixels would be discarded early. --- irr/src/COpenGLSLMaterialRenderer.cpp | 20 ++++---------------- irr/src/COpenGLSLMaterialRenderer.h | 1 - src/client/shader.cpp | 9 +-------- 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/irr/src/COpenGLSLMaterialRenderer.cpp b/irr/src/COpenGLSLMaterialRenderer.cpp index 373f79b54f..4471b95466 100644 --- a/irr/src/COpenGLSLMaterialRenderer.cpp +++ b/irr/src/COpenGLSLMaterialRenderer.cpp @@ -40,7 +40,7 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver *drive E_MATERIAL_TYPE baseMaterial, s32 userData) : Driver(driver), - CallBack(callback), Alpha(false), Blending(false), AlphaTest(false), Program(0), Program2(0), UserData(userData) + CallBack(callback), Alpha(false), Blending(false), Program(0), Program2(0), UserData(userData) { switch (baseMaterial) { case EMT_TRANSPARENT_VERTEX_ALPHA: @@ -50,9 +50,6 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver *drive case EMT_ONETEXTURE_BLEND: Blending = true; break; - case EMT_TRANSPARENT_ALPHA_CHANNEL_REF: - AlphaTest = true; - break; default: break; } @@ -72,7 +69,7 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver *driver, IShaderConstantSetCallBack *callback, E_MATERIAL_TYPE baseMaterial, s32 userData) : Driver(driver), - CallBack(callback), Alpha(false), Blending(false), AlphaTest(false), Program(0), Program2(0), UserData(userData) + CallBack(callback), Alpha(false), Blending(false), Program(0), Program2(0), UserData(userData) { switch (baseMaterial) { case EMT_TRANSPARENT_VERTEX_ALPHA: @@ -82,9 +79,6 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver *driver, case EMT_ONETEXTURE_BLEND: Blending = true; break; - case EMT_TRANSPARENT_ALPHA_CHANNEL_REF: - AlphaTest = true; - break; default: break; } @@ -210,11 +204,11 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial &material, Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); + cacheHandler->setAlphaTest(false); + if (Alpha) { cacheHandler->setBlend(true); cacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - cacheHandler->setAlphaTest(true); - cacheHandler->setAlphaFunc(GL_GREATER, 0.f); } else if (Blending) { E_BLEND_FACTOR srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact; E_MODULATE_FUNC modulate; @@ -229,9 +223,6 @@ void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial &material, } cacheHandler->setBlend(true); - } else if (AlphaTest) { - cacheHandler->setAlphaTest(true); - cacheHandler->setAlphaFunc(GL_GREATER, 0.5f); } if (CallBack) @@ -249,9 +240,6 @@ void COpenGLSLMaterialRenderer::OnUnsetMaterial() if (Alpha || Blending) { cacheHandler->setBlend(false); } - if (Alpha || AlphaTest) { - cacheHandler->setAlphaTest(false); - } } //! Returns if the material is transparent. diff --git a/irr/src/COpenGLSLMaterialRenderer.h b/irr/src/COpenGLSLMaterialRenderer.h index 3b8e83674b..de15f9fbbe 100644 --- a/irr/src/COpenGLSLMaterialRenderer.h +++ b/irr/src/COpenGLSLMaterialRenderer.h @@ -96,7 +96,6 @@ protected: bool Alpha; bool Blending; - bool AlphaTest; struct SUniformInfo { diff --git a/src/client/shader.cpp b/src/client/shader.cpp index 9a1cdc409b..034a8ffb12 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -790,14 +790,7 @@ void ShaderSource::generateShader(ShaderInfo &shaderinfo) ShaderConstants constants = input_const; - bool use_discard = m_fully_programmable; - if (!use_discard) { - // workaround for a certain OpenGL implementation lacking GL_ALPHA_TEST - const char *renderer = reinterpret_cast(GL.GetString(GL.RENDERER)); - if (strstr(renderer, "GC7000")) - use_discard = true; - } - if (use_discard) { + { if (shaderinfo.base_material == video::EMT_TRANSPARENT_ALPHA_CHANNEL) constants["USE_DISCARD"] = 1; else if (shaderinfo.base_material == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF)