C#体素生成奇怪的故障

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

我正在尝试在 C# 中生成体素,但有一个奇怪的错误。
我已经用 C# 生成了其他体素,但从未遇到过这个错误;

看起来像这样:

######
####
####
#
#
#

[有关图片,请参阅 reddit 上的帖子。]

我尝试了多种方法,但只有一种方法有效,在每一代之间等待一帧。

加载块数组的代码:

public void Update(float state) 
{
     if (chunkQueue.Any()) chunkService.LoadChunk(chunkQueue.Dequeue());

     var cameraPosition = cameraSet.GetEntities()[0].Get<Transform>().Position;
     var cameraChunkPosition = new Vector2Int
     {
         X = (int)Math.Floor(cameraPosition.X / 16),
         Y = (int)Math.Floor(cameraPosition.Z / 16)
     };

     for (int x = 0; x < renderDistance; x++)
     {
         for (int z = 0; z < renderDistance; z++)
         {
              var chunkPosition = cameraChunkPosition + 
                  new Vector2Int(x - halfRenderDistance, z - halfRenderDistance);

              if (existingChunk.Contains(chunkPosition)) continue;

              chunkService.LoadChunk(chunkPosition);
             // chunkQueue.Enqueue(chunkPosition);
             existingChunk.Add(chunkPosition);
        }
    }
} 

但是如果我取消注释 //chunkQueue.Enqueue(chunkPosition);

并注释 chunkService.LoadChunk(chunkPosition);

正确生成如下:

######
######
######
######
######
######

[有关图片,请参阅 reddit 上的帖子。]

为什么会发生这种情况?

我猜是记忆有问题还是什么的。

块生成发生在这个文件中:

using DefaultEcs;
using Flux.Core.Rendering;
using Flux.Core.ServiceAbstraction;
using Flux.Core.Services;

namespace MinecraftClone;

class ChunkService
{
    readonly IEcsService ecsService;
    readonly GL gl;
    readonly TerrainService terrainService;
    readonly Shader globalShader;

    public ChunkService(IEcsService ecsService, GL gl, ResourcesService resourcesService, TerrainService terrainService)
    {
        this.ecsService = ecsService;
        this.gl = gl;
        this.terrainService = terrainService;
        globalShader = resourcesService.LoadShader("Chunk.vert", "Chunk.frag");
    }

    public Entity LoadChunk(Vector2Int chunkPosition)
    {
        var blocks = GenerateChunkData(chunkPosition, terrainService);

        var vertexs = new List<float>(16 * 16 * 16 * 6);
        var faces = new List<uint[]>();

        for (int x = 0; x < ChunkMath.ChunkSize; x++)
        {
            for (int y = 0; y < ChunkMath.ChunkSize; y++)
            {
                for (int z = 0; z < ChunkMath.ChunkSize; z++)
                {
                    var isFull = blocks[x, y, z];

                    if (!isFull)
                        continue;

                    var blockPosition = new Vector3Int(x, y, z);

                    vertexs.AddRange(BlockData.OffsetFace(BlockData.XFaceVertex, blockPosition));
                    faces.Add(BlockData.XFaceIndice);

                    vertexs.AddRange(BlockData.OffsetFace(BlockData.NegXFaceVertex, blockPosition));
                    faces.Add(BlockData.NegXFaceIndice);

                    vertexs.AddRange(BlockData.OffsetFace(BlockData.YFaceVertex, blockPosition));
                    faces.Add(BlockData.YFaceIndice);

                    vertexs.AddRange(BlockData.OffsetFace(BlockData.NegYFaceVertex, blockPosition));
                    faces.Add(BlockData.NegYFaceIndice);

                    vertexs.AddRange(BlockData.OffsetFace(BlockData.ZFaceVertex, blockPosition));
                    faces.Add(BlockData.ZFaceIndice);

                    vertexs.AddRange(BlockData.OffsetFace(BlockData.NegZFaceVertex, blockPosition));
                    faces.Add(BlockData.NegZFaceIndice);

                }
            }
        }


        var indexes = ComputeIndexes(faces);

        var entity = ecsService.World.CreateEntity();
        entity.Set(chunkPosition);
        entity.Set(new Chunk(gl, globalShader, vertexs.ToArray(), indexes));
        return entity;
    }

    private static uint[] ComputeIndexes(List<uint[]> faces)
    {
        var indices = new uint[faces.Count * 6];
        for (int i = 0; i < faces.Count; i++)
        {
            var face = faces[i];
            uint indiceOffset = (uint)i * 6;
            uint vertexOffset = (uint)i * 4;
            for (int ii = 0; ii < 6; ii++)
            {
                indices[indiceOffset + ii] = face[ii] + vertexOffset;
            }
        }

        return indices;
    }

    static bool[,,] GenerateChunkData(Vector2Int chunkPosition, TerrainService terrainService)
    {
        var blocks = new bool[ChunkMath.ChunkSize, ChunkMath.ChunkSize, ChunkMath.ChunkSize];

        for (int x = 0; x < ChunkMath.ChunkSize; x++)
        {
            for (int y = 0; y < ChunkMath.ChunkSize; y++)
            {
                for (int z = 0; z < ChunkMath.ChunkSize; z++)
                {
                    var blockX = x + (chunkPosition.X * ChunkMath.ChunkSize);
                    var blockZ = z + (chunkPosition.Y * ChunkMath.ChunkSize);
                    var isFull = y < terrainService.GetHeight(blockX, blockZ, 16);

                    blocks[x, y, z] = isFull;
                }
            }
        }

        return blocks;
    }
}
c# .net-core procedural-generation voxel
© www.soinside.com 2019 - 2024. All rights reserved.