Почему Transvoxel делает густую местность?

С тех пор я работаю над реализацией Transvoxel. Теперь это работает, это полигонизирует, но это своего рода блокирует. Как изображение ниже:

Это код для полигонизации:

private static Mesh PolygonizeRegularCell (Vector3i pos, Mesh mesh, int lodIndex, Chunk samples)
{
    int lod = 1 << lodIndex;

    for (int i = 0; i < density.Length; i++) {
        density [i] = samples [pos + Transvoxel.cornerIndex [i] * lod].Density;
    }

    byte caseCode = getCaseCode(density);

    if ((caseCode ^ ((density [7] >> 7) & 0xFF)) != 0) {
        byte cellClass = Transvoxel.regularCellClass [caseCode];
        vertexLocations = Transvoxel.regularVertexData [caseCode];

        Transvoxel.RegularCell c = Transvoxel.regularCellData [cellClass];
        vertexCount = (long)c.GetVertexCount ();
        triangleCount = (long)c.GetTriangleCount ();
        indexOffset = c.Indizes ();

        localVertexMapping = new int[indexOffset.Length];

        for (int i = 0; i < vertexCount; i++) {
            ushort edgeCode = (ushort)(vertexLocations [i] & 0xFF);

            byte v0 = (byte)((edgeCode >> 4) & 0x0F);
            byte v1 = (byte)(edgeCode & 0x0F);

            Vector3 p0 = (pos + Transvoxel.cornerIndex [v0] * lod).ToVector3 ();
            Vector3 p1 = (pos + Transvoxel.cornerIndex [v1] * lod).ToVector3 ();

            long t = (density [v1] << 8) / (density [v1] - density [v0]);
            long u = 0x0100 - t;

            localVertexMapping [i] = vertices.Count;
            Vector3 Q = p0 * t + p1 * u;
            Q /= 256f;
            AddVertex (Q, samples [pos.x, pos.y, pos.z].block);
        }

        for (int t = 0; t < triangleCount; t++) {
            for (int i = 0; i < 3; i++) {
                triangles.Add (localVertexMapping [c.Indizes () [t * 3 + i]]);
            }
        }
    }
    return mesh;
}

А вот еще один для генерации карты высот и значений плотности:

public void GenerateNewDensityField (int x, int z)
{
    densityColumn = new sbyte[128];
    noise = (float)(Noise.noise (x * 0.01f, z * 0.01f) * 0.25f);
    fHeight = ((noise + 1f) * 54f) + worldSize;
    height = Mathf.FloorToInt (fHeight);
    for (int i = 0; i < densityColumn.Length; i++) {
        if (i < height - 1)
            densityColumn [i] = -128;
        else if (i == height - 1)
            densityColumn [height - 1] = (sbyte)Mathf.Clamp (height - 128, -127, 128);
        else if (i == height)
            densityColumn [height] = (sbyte)Mathf.Clamp (-height, -128, 127);
        else if (i == height + 1)
            densityColumn [height + 1] = (sbyte)Mathf.Clamp (127 - height, -128, 127);
        else
            densityColumn [i] = 127;
    }

    densityCache [x, z] = new DensityColumn (densityColumn, height);
}

Если вы уже использовали Transvoxel или у вас есть идеи по этому поводу, пожалуйста, прокомментируйте или ответьте. Я действительно застрял с этим.

РЕДАКТИРОВАТЬ: Изменения в коде генерации плотности, чтобы не генерировать слишком много нулей и т. Д., Но он все еще блочный.

1 ответ

Я не рассмотрел ваш код подробно, но блочный рисунок на скриншоте напоминает неточные значения плотности вокселей. Например, вы могли бы увидеть этот шаблон, если бы все значения данных вокселей были -1,0 или +1,0 (или -127 и +127 как целочисленные данные) без каких-либо промежуточных значений. Вокселы должны представлять расстояние до поверхности в единицах ширины одного вокселя, при этом +127 означает, что точка данных находится на один воксел вне поверхности, а -127 означает, что точка данных - это один воксел внутри поверхности. Возможно, вам просто нужно соответственно изменить масштаб ваших данных, и тогда вы увидите гладкие результаты.

Другие вопросы по тегам