From e740cf1214ed0b430598c304f0ad0b5de07ab070 Mon Sep 17 00:00:00 2001 From: emil28092005 Date: Thu, 18 Jun 2026 12:42:13 +0300 Subject: [PATCH] fix: compute face normals when OBJ has no vn lines - ObjLoader.ParseFace: if no normals in OBJ, compute face normal from first triangle using MeshMath.ComputeFaceNormal and apply to all face vertices - cube.obj has no vn lines, so all faces previously had normal (0,1,0) - Now each face has correct outward-facing normal for proper lighting --- src/Engine.Graphics/Loaders/ObjLoader.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Engine.Graphics/Loaders/ObjLoader.cs b/src/Engine.Graphics/Loaders/ObjLoader.cs index a7acbc9..9644180 100644 --- a/src/Engine.Graphics/Loaders/ObjLoader.cs +++ b/src/Engine.Graphics/Loaders/ObjLoader.cs @@ -3,7 +3,6 @@ using Engine.Core; using Engine.Core.Components; namespace Engine.Graphics.Loaders; - /// /// Minimal OBJ loader. /// @@ -66,6 +65,8 @@ public static class ObjLoader var faceIndices = new List(); faceNormals.Clear(); + var hasNormals = false; + for (int i = 1; i < parts.Length; i++) { var sub = parts[i].Split('/'); @@ -76,13 +77,27 @@ public static class ObjLoader if (sub.Length > 2 && !string.IsNullOrEmpty(sub[2])) { normal = normals[int.Parse(sub[2]) - 1]; + hasNormals = true; } vertices.Add(new Vertex(pos, color, normal)); faceIndices.Add((uint)(vertices.Count - 1)); } - // Triangulate as a fan. + if (!hasNormals && faceIndices.Count >= 3) + { + var a = vertices[(int)faceIndices[0]].Position; + var b = vertices[(int)faceIndices[1]].Position; + var c = vertices[(int)faceIndices[2]].Position; + var faceNormal = MeshMath.ComputeFaceNormal(a, b, c); + for (int i = 0; i < faceIndices.Count; i++) + { + var v = vertices[(int)faceIndices[i]]; + v.Normal = faceNormal; + vertices[(int)faceIndices[i]] = v; + } + } + for (int i = 2; i < faceIndices.Count; i++) { indices.Add(faceIndices[0]);