From ae20fbf621923fccaee3d4655ea8ec9e5b58c3f0 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 08:47:31 -0700 Subject: [PATCH] fix(wmo): degenerate-normal guard during tangent generation A WMO vertex with zero-length or NaN normal would produce a NaN normalized normal, contaminating the Gram-Schmidt tangent for the whole vertex and producing visibly broken normal mapping for the affected face. Length-check before normalize and fall back to (0,0,1) when degenerate. --- src/rendering/wmo_renderer.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/rendering/wmo_renderer.cpp b/src/rendering/wmo_renderer.cpp index fce12661..e75cda69 100644 --- a/src/rendering/wmo_renderer.cpp +++ b/src/rendering/wmo_renderer.cpp @@ -1869,7 +1869,16 @@ bool WMORenderer::createGroupResources(const pipeline::WMOGroup& group, GroupRes } for (size_t i = 0; i < vertices.size(); i++) { - glm::vec3 n = glm::normalize(vertices[i].normal); + // Vertex normals from corrupt WMO data could be zero-length or + // NaN. glm::normalize on either returns NaN that contaminates + // the entire Gram-Schmidt tangent below; fall back to up-axis. + glm::vec3 n; + float normLen = glm::length(vertices[i].normal); + if (std::isfinite(normLen) && normLen > 1e-6f) { + n = vertices[i].normal / normLen; + } else { + n = glm::vec3(0, 0, 1); + } glm::vec3 t = tan1[i]; if (glm::dot(t, t) < 1e-8f) {