0

I am trying to implement the Transvoxel algorithm for a game I am working on but I'm noticing some weird issues in the mesh generated:

Not sure why there are gaps and why the sphere has fins behind it.

For some reason, the mesh has gaps between chunks, and it has these strange fins extending out behind it. I haven't been able to figure out why this is happening but I have an inkling it may have to do with either the function that generates the density values for each Chunk (16x16x16 Block of cells):

    private float SampleDensity(float3 _point)
    {
        var _worldPos = (_point / (m_WorldRadius - 1.0f) - 0.5f) * m_VolumeFieldSize;
        var _halfS = m_VolumeFieldSize / 2;
        var _maxD= Magnitude(new float3(_halfS, _halfS, _halfS));
        var _fudge = 1f;

        var _density = Magnitude(_worldPos) / (_maxD + _fudge) - 0.5f;
        var _noise = CalculateNoise(_worldPos);
        
        _density += _noise;
        return _density;
    }
    
    public void Execute()
    {
        for (int _z = 0; _z < m_ChunkSize; _z++)
        {
            for (int _y = 0; _y < m_ChunkSize; _y++)
            {
                for (int _x = 0; _x < m_ChunkSize; _x++)
                {
                    var _point = (new float3(_x, _y, _z) + (m_GPosition)); // Multiplying or dividing this value adjusts the final mesh's scale.
                    var _valueAtPoint = SampleDensity(_point);
                    m_Cells[_z * m_ChunkSize * m_ChunkSize + _y * m_ChunkSize + _x] = _valueAtPoint;
                }
            }
        }
    }

, or the mesh generating code itself:

    for (int _z = 0; _z < _chunk.m_ChunkSize; _z++)
        {
            for (int _y = 0; _y < _chunk.m_ChunkSize; _y++)
            {
                for (int _x = 0; _x < _chunk.m_ChunkSize; _x++)
                {
                    var _cubeConfiguration = 0;
                    for (int _i = 0; _i < 8; _i++)
                    {
                        _cornerPos = CornerIndex[_i];
                        _densityValues[_i] = _chunk.GetCell(_x + _cornerPos.x, _y + _cornerPos.y, _z + _cornerPos.z);

                        if (_densityValues[_i] < _chunk.m_World.m_ISOLevel) _cubeConfiguration |= (1 << _i);
                    }

                    var _caseCode = (byte) _cubeConfiguration;
                    if (_caseCode == 0) continue;

                    for (int _i = 0; _i < _cornerNormals.Length; _i++)
                    {
                        _cornerPos = CornerIndex[_i];
                        _cornerNormals[_i] = new Vector3(
                            _chunk.GetCell(_x + _cornerPos.x - 1, _y + _cornerPos.y, _z + _cornerPos.z) - _chunk.GetCell(_x + _cornerPos.x + 1, _y + _cornerPos.y, _z + _cornerPos.z),
                            _chunk.GetCell(_x + _cornerPos.x, _y + _cornerPos.y - 1, _z + _cornerPos.z) - _chunk.GetCell(_x + _cornerPos.x, _y + _cornerPos.y + 1, _z + _cornerPos.z),
                            _chunk.GetCell(_x + _cornerPos.x, _y + _cornerPos.y, _z + _cornerPos.z - 1) - _chunk.GetCell(_x + _cornerPos.x, _y + _cornerPos.y, _z + _cornerPos.z + 1)
                        );
                    }
                    
                    var _cellClass = Transvoxel.regularCellClass[_caseCode];
                    Debug.Log($"Cell Class {_cellClass}");
                    
                    var _vertexLocations = Transvoxel.RegularVertexData[_caseCode];

                    var _cellData = Transvoxel.RegularCellDatas[_cellClass];
                    
                    var _vertexCount = _cellData.GetVertexCount();
                    var _triangleCount = _cellData.GetTriangleCount();
                    var _indexOffset = _cellData.vertexIndex;
                    
                    for (int _i = 0; _i < _vertexCount; _i++)
                    {
                        ushort _edge = (ushort)(_vertexLocations[_i] & 255);

                        byte _v0 = (byte)((_edge >> 4) & 0x0F); //First Corner Index
                        byte _v1 = (byte)(_edge & 0x0F); //Second Corner Index

                        float _t = (_densityValues[_v1]) / (_densityValues[_v1] - _densityValues[_v0]);
                        
                        Vector3 _p0 = new Vector3((_x + CornerIndex[_v0].x), (_y + CornerIndex[_v0].y), (_z + CornerIndex[_v0].z));
                        Vector3 _p1 = new Vector3((_x + CornerIndex[_v1].x), (_y + CornerIndex[_v1].y), (_z + CornerIndex[_v1].z));

                        var _position = (_p0 * _t) + ((1 - _t) * _p1);

                        var _n0 = CalculateNormal(_chunk, new Vector3Int((int) _p0.x, (int) _p0.y, (int) _p0.z));
                        var _n1 = CalculateNormal(_chunk, new Vector3Int((int) _p1.x, (int) _p1.y, (int) _p1.z));

                        var _normal = (_n0 + _t * (_n1 - _n0)).normalized;

                        m_Normals.Add(_normal);
                        m_Vertices.Add(_position);
                        m_UVs.Add(UvOffset[m_VCase]);

                        m_VCase = (byte)(m_VCase == 3 ? 0 : m_VCase + 1);
                        m_LocalVertexMapping[_i] = (ushort)(m_Vertices.Count - 1);
                    }

                    for (int _t = 0; _t < _triangleCount; _t++)
                    {
                        int _tm = _t * 3;
                        m_Triangles.Add(m_LocalVertexMapping[_indexOffset[_tm]]);
                        m_Triangles.Add(m_LocalVertexMapping[_indexOffset[_tm + 1]]);
                        m_Triangles.Add(m_LocalVertexMapping[_indexOffset[_tm + 2]]);
                    }
                }
            }
        }

I am at a complete loss and would really appreciate some help as I've been racking my brains for close to 2 months on this, along with reading several papers on different MC Algorithms (Lengyel's included) for potential inspiration. Thank You.

  • I'm not reading thoroughly the whole code but I can give a few investigation pointers: Your gaps look very much like an off-by-one error. One thing to notice is that for a chunk of NxNxN cubes, you actually need to consider densities on N+1 points along each axis. Also if you want proper normals (yours look off, maybe for that reason), you need to consider N+3 points. – Gnurfos Jun 24 '22 at 11:16
  • The fins you see might be just a consequence of that too, but if not, to investigate them: add logs as you output vertices, and filter the logs (or add an if in the code) to find when you are outputing outside of the expected range. Work your way up from there (with more logs, or debugging) – Gnurfos Jun 24 '22 at 11:16

0 Answers0