From 32cc13d1b2134ba93c19054967a9c88bddd936e9 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Thu, 19 Feb 2026 18:23:59 -0800 Subject: [PATCH] Fix torch models eaten by glow sprites, fix lantern glow black backgrounds Two fixes: 1. shouldUseGlowSprite now requires the UNLIT material flag (0x01) for the colorKeyBlack+flameLikeModel path. Previously, structural geometry (torch handles, sconce brackets) on flame-like models got replaced with glow sprites because their texture paths contained keywords like "torch" in the directory name, setting colorKeyBlack on non-glow textures. Requiring UNLIT ensures only actual glow/emissive batches become sprites while lit structural geometry renders normally. 2. Fragment shader now discards near-black (maxRGB < 0.1) for ALL unlit non-opaque batches, not just additive blend modes. Glow effects on lanterns/lamps that use blendMode 1 (AlphaKey) or 2 (Alpha) instead of 3 (Additive) now properly discard their black backgrounds. --- src/rendering/m2_renderer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/rendering/m2_renderer.cpp b/src/rendering/m2_renderer.cpp index f11a298f..d3015792 100644 --- a/src/rendering/m2_renderer.cpp +++ b/src/rendering/m2_renderer.cpp @@ -368,6 +368,11 @@ bool M2Renderer::initialize(pipeline::AssetManager* assets) { if ((uBlendMode == 3 || uBlendMode == 6) && maxRgb < 0.1) { discard; } + // Unlit non-opaque batches (glow effects, emissive surfaces) with + // near-black pixels: these are glow textures where black = transparent. + if (uUnlit && uBlendMode >= 1 && maxRgb < 0.1) { + discard; + } // Distance fade - discard nearly invisible fragments float finalAlpha = texColor.a * uFadeAlpha; @@ -2018,10 +2023,12 @@ void M2Renderer::render(const Camera& camera, const glm::mat4& view, const glm:: // Replace only likely flame-card submeshes with sprite glow. Keep larger geometry // (lantern housings, posts, etc.) authored so the prop itself remains visible. const bool smallCardLikeBatch = (batch.glowSize <= 1.35f); + const bool batchUnlit = (batch.materialFlags & 0x01) != 0; const bool shouldUseGlowSprite = !koboldFlameCard && smallCardLikeBatch && - ((batch.blendMode >= 3) || (batch.colorKeyBlack && flameLikeModel && batch.blendMode >= 1)); + ((batch.blendMode >= 3) || + (batch.colorKeyBlack && flameLikeModel && batchUnlit && batch.blendMode >= 1)); if (shouldUseGlowSprite) { if (entry.distSq < 180.0f * 180.0f) { glm::vec3 worldPos = glm::vec3(instance.modelMatrix * glm::vec4(batch.center, 1.0f));