From 9ebfc9b21fef23992fac8a4df93fbbf379d7bbba Mon Sep 17 00:00:00 2001 From: Kelsi Date: Mon, 9 Feb 2026 18:13:05 -0800 Subject: [PATCH] Fix completely black WMO areas caused by zero vertex colors The issue was that vertex colors (MOCV) were being multiplied directly into the texture color BEFORE lighting calculation. When MOCV data contained black (0,0,0) values, this zeroed out the texture color, making all subsequent lighting multiplication also zero, resulting in pitch black areas regardless of ambient light settings. Fixed by: 1. Removed premature vertex color multiplication from texture sampling 2. Applied vertex colors as ambient occlusion AFTER lighting calculation 3. Clamped vertex colors to minimum 0.5 to prevent complete blackout Now even areas with black MOCV data will render at 50% brightness minimum, while properly lit areas remain bright. This preserves the AO effect without causing invisible geometry. --- src/rendering/wmo_renderer.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/rendering/wmo_renderer.cpp b/src/rendering/wmo_renderer.cpp index cba38be7..a5b4c0cd 100644 --- a/src/rendering/wmo_renderer.cpp +++ b/src/rendering/wmo_renderer.cpp @@ -110,11 +110,8 @@ bool WMORenderer::initialize(pipeline::AssetManager* assets) { // Alpha test only for cutout materials (lattice, grating, etc.) if (uAlphaTest && texColor.a < 0.5) discard; alpha = texColor.a; - // Exterior: multiply vertex color (MOCV baked AO) into texture - // Interior: keep texture clean — vertex color is used as light below - if (!uIsInterior) { - texColor.rgb *= VertexColor.rgb; - } + // Don't multiply texture by vertex color here - it zeros out black MOCV areas + // Vertex colors will be applied as AO modulation after lighting } else { // MOCV vertex color alpha is a lighting blend factor, not transparency texColor = vec4(VertexColor.rgb, 1.0); @@ -177,6 +174,11 @@ bool WMORenderer::initialize(pipeline::AssetManager* assets) { shadow = mix(1.0, shadow, clamp(uShadowStrength, 0.0, 1.0)); litColor = (ambient + (diffuse + specular) * shadow) * texColor.rgb; + + // Apply vertex color as ambient occlusion (AO) with minimum to prevent blackout + // MOCV values of (0,0,0) are clamped to 0.5 to keep areas visible + vec3 ao = max(VertexColor.rgb, vec3(0.5)); + litColor *= ao; } // Fog