You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity3D中Marching Cubes网格异常光照问题求助

Unity中Marching Cubes平滑着色后光照异常排查

我正在Unity中实现Marching Cubes算法,给网格加上平滑着色后出现了异常光照效果。我对Marching Cubes算法不太熟悉,但Perlin Noise的使用经验很丰富。以下是实现核心逻辑的完整代码(示例中移除了三角化表):

public bool smoothTerrain;
public bool flatShaded;

private List<Vector3> vertices = new List<Vector3>();
private List<int> triangles = new List<int>();

private MeshFilter meshFilter;

private float terrainSurface = 0.5f;
private float noiseScale = 0.09f;
private int size = 30;

private void Awake() {

    meshFilter = GetComponent<MeshFilter>();
    CreateMeshData();
    BuildMesh();

}

void CreateMeshData() {

    for (int x = 0; x < size; x++) {
        for (int y = 0; y < size; y++) {
            for (int z = 0; z < size; z++) {

                float[] cube = new float[8];
                for (int i = 0; i < 8; i++) {
                        
                    Vector3Int corner = new Vector3Int(x, y, z) + CornerTable[i];
                    cube[i] = Noise.Perlin3D(corner.x * noiseScale + 100000f, corner.y * noiseScale + 300000f, corner.z * noiseScale + 500000f);

                }

                MarchCube(new Vector3Int(x, y, z), cube);

            }
        }
    }

}

int GetCubeConfiguration(float[] cube) {

    int configurationIndex = 0;
    for (int i = 0; i < 8; i++) {

        if (cube[i] > terrainSurface)
            configurationIndex |= 1 << i;

    }

    return configurationIndex;

}

int VertForIndice(Vector3 vert) {

    for (int i = 0; i < vertices.Count; i++) {

        if (vertices[i] == vert)
            return i;

    }

    vertices.Add(vert);
    return vertices.Count - 1;

}

void MarchCube(Vector3Int position, float[] cube) {

    int configIndex = GetCubeConfiguration(cube);
    
    if (configIndex == 0 || configIndex == 255)
        return;

    int edgeIndex = 0;
    for (int i = 0; i < 5; i++) {
        for (int p = 0; p < 3; p++) {

            int indice = TriangleTable[configIndex, edgeIndex];

            if (indice == -1)
                return;

            Vector3 vert1 = position + CornerTable[EdgeIndexes[indice, 0]];
            Vector3 vert2 = position + CornerTable[EdgeIndexes[indice, 1]];
            
            Vector3 vertPosition;
            if (smoothTerrain) {
                
                float vert1Sample = cube[EdgeIndexes[indice, 0]];
                float vert2Sample = cube[EdgeIndexes[indice, 1]];

                float difference = vert2Sample - vert1Sample;

                if (difference == 0)
                    difference = terrainSurface;
                else
                    difference = (terrainSurface - vert1Sample) / difference;

                vertPosition = vert1 + ((vert2 - vert1) * difference);
            } else {

                vertPosition = (vert1 + vert2) / 2f;

            }

            if (flatShaded) {
                vertices.Add(vertPosition);
                triangles.Add(vertices.Count - 1);
            } else {
                triangles.Add(VertForIndice(vertPosition));
            }
            
            edgeIndex++;

        }
    }

}

void ClearMeshData() {
    
    vertices.Clear();
    triangles.Clear();

}

void BuildMesh() {

    Mesh mesh = new Mesh();
    mesh.vertices = vertices.ToArray();
    mesh.triangles = triangles.ToArray();
    mesh.RecalculateNormals();
    meshFilter.mesh = mesh;

}

Vector3Int[] CornerTable = new Vector3Int[8] {

    new Vector3Int(0, 0, 0),
    new Vector3Int(1, 0, 0),
    new Vector3Int(1, 1, 0),
    new Vector3Int(0, 1, 0),
    new Vector3Int(0, 0, 1),
    new Vector3Int(1, 0, 1),
    new Vector3Int(1, 1, 1),
    new Vector3Int(0, 1, 1)

};

int[,] EdgeIndexes = new int[12, 2] {

    {0, 1}, {1, 2}, {3, 2}, {0, 3}, {4, 5}, {5, 6}, {7, 6}, {4, 7}, {0, 4}, {1, 5}, {2, 6}, {3, 7}

};

附异常光照效果、整体网格及线框模式截图:

异常光照
整体网格
线框模式

希望有人能帮忙排查异常光照的原因,或提供排查方向。

内容的提问来源于stack exchange,提问作者cooldev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 10:35:16