地形网格生成算法开启LOD后出现视觉artifacts的故障排查问询
故障原因
- 核心错误:
GenerateTerrainMesh函数调用InitializeMeshTerrain时参数传递错误,你分别计算了X、Y方向的顶点数VerticesPerLineX和VerticesPerLineY,但调用初始化函数时两次传入了VerticesPerLineX,导致网格内存分配错误、顶点和索引写入越界错位,是出现异常网格的直接原因。 - 潜在错误:当前三角形生成的边界判断逻辑存在问题,当噪声图宽高不是简化步长的整数倍时,会生成无效的边缘三角形;同时三角形顶点缠绕顺序可能和你渲染器的背面剔除规则不匹配,导致部分面被错误剔除。
修复后的核心代码
static void GenerateTerrainMesh(world* World, noise_map* NoiseMap, float HeightMultiplier, int LevelOfDetail) { int Width = NoiseMap->Width; int Height = NoiseMap->Height; if(LevelOfDetail < 0) LevelOfDetail = 0; if(LevelOfDetail > 6) LevelOfDetail = 6; int SimplificationInc = (LevelOfDetail == 0) ? 1 : (LevelOfDetail * 2); int VerticesPerLineX = (Width - 1) / SimplificationInc + 1; int VerticesPerLineY = (Height - 1) / SimplificationInc + 1; // 修正初始化参数,传入正确的Y方向顶点数 InitializeMeshTerrain(World, VerticesPerLineX, VerticesPerLineY); int VertIndex = 0; int TrigIndex = 0; for(int Y = 0; Y < Height; Y += SimplificationInc) { for(int X = 0; X < Width; X += SimplificationInc) { World->Terrain.Vertices[VertIndex] = V3((float)X, HeightMultiplier * HeightFlatten(World->NoiseMap.Values[Y*World->NoiseMap.Width + X]).y * HeightMultiplier, (float)Y); World->Terrain.UVs[VertIndex] = V2(X/(float)Width, Y/(float)Height); // 修正边界判断,避免生成超出网格范围的三角形 if(X < Width - SimplificationInc && Y < Height - SimplificationInc) { // 可根据你的背面剔除规则调整顶点顺序 AddTriangle(World, &TrigIndex, VertIndex, VertIndex + VerticesPerLineX, VertIndex + VerticesPerLineX + 1); AddTriangle(World, &TrigIndex, VertIndex + VerticesPerLineX + 1, VertIndex + 1, VertIndex); } VertIndex += 1; } } }
内容的提问来源于stack exchange,提问作者Zhukov Artem
相关产品推荐
相关产品推荐

