重新计算已编辑高度图的法线

问题描述 投票:0回答:0

我有一个用 C# 和 Monogame 编写的地形编辑器。编辑地形后,我只想重新计算与实际改变位置的三角形关联的顶点的法线。但是,我遇到了一个问题,即编辑区域周围总是有一个“环”,其法线似乎不匹配。如果我在编辑地形后重新计算网格的所有法线,它看起来是正确的。

这是一张图片,显示仅在受影响的三角形上计算法线

这是它应该是什么样子的图像。这里的法线以相同的方式计算,只是针对每个顶点,而不是仅针对与三角形关联的顶点

这是我目前如何重新计算与实际改变的三角形相关联的顶点的法线

        private void RecalculateNormals(Terrain terrain, List<int> uniqueVertexIndex)
        {
            List<int[]> totalTriangles = new List<int[]>();
            List<int> verticesToNormalize = new List<int>();
            foreach (int vertexIndex in uniqueVertexIndex)
            {
                Console.WriteLine("Vertex Position Changed: " + vertexIndex);
                foreach (int[] triangle in terrain.Collider.lookupTrianglesAttachedToVertex(vertexIndex))
                {
                    bool skip = false;
                    foreach (int[] testTriangle in totalTriangles)
                        if (triangle[0] == testTriangle[0])
                        {
                            skip = true;
                        }
                    if (!skip)
                    {
                        totalTriangles.Add(triangle);
                        foreach (int index in triangle)
                        {
                            if (!verticesToNormalize.Contains(terrain.Mesh.Indices[index]))
                            {
                                verticesToNormalize.Add(terrain.Mesh.Indices[index]);
                            }
                        }
                    }
                }
            }
 
            foreach (int vertex in verticesToNormalize)
            {
                terrain.Mesh.Vertices[vertex].Normal = new Vector3(0, 0, 0);
                Console.WriteLine("Vertex Updating: " + vertex);
            }
 
            foreach (int[] triangle in totalTriangles)
            {
                int index1 = terrain.Mesh.Indices[triangle[0]];
                int index2 = terrain.Mesh.Indices[triangle[1]];
                int index3 = terrain.Mesh.Indices[triangle[2]];
                Vector3 side1 = terrain.Mesh.Vertices[index3].Position - terrain.Mesh.Vertices[index2].Position;
                Vector3 side2 = terrain.Mesh.Vertices[index2].Position - terrain.Mesh.Vertices[index1].Position;
                Vector3 normal = Vector3.Cross(side1, side2);
            
                terrain.Mesh.Vertices[index1].Normal += normal;
                terrain.Mesh.Vertices[index2].Normal += normal;
                terrain.Mesh.Vertices[index3].Normal += normal;
 
                Console.WriteLine("Recalculated Normals on Triangle: " + triangle[0] + " " + index1 + " | " + triangle[1] + " " + index2 + " | " + triangle[2] + " " + index3);
 
            }
 
            foreach (int vertex in verticesToNormalize)
               terrain.Mesh.Vertices[vertex].Normal.Normalize();
 
        }

这里是一个包含更多相关代码的 pastebin。我不确定我在这里遗漏了什么,或者我是否误解了法线的计算方式:https://pastebin.com/KTLq2CY1

c# unity3d monogame normals
© www.soinside.com 2019 - 2024. All rights reserved.