protected override void OnUpdate() { var ecb = _commandsBuffer.CreateCommandBuffer().ToConcurrent(); Entities.WithAll <ChunkTag, UpdateChunkTag, CalculateFacesTag>() .ForEach( ( Entity e, int entityInQueryIndex, ref DynamicBuffer <VoxelBufferElement> voxelBuffer, ref DynamicBuffer <VisibleFacesBufferElement> visibleFacesBuffer ) => { for (var x = 0; x < ChunkSize; ++x) { for (var y = 0; y < ChunkSize; ++y) { for (var z = 0; z < ChunkSize; ++z) { VisibleFacesBufferElement face; var voxel = voxelBuffer[GetIndex(x, y, z)].value; if (!IsOpaque(voxel)) { face = VisibleFacesBufferElement.None; } else { var left = x >= 1 && IsOpaque(voxelBuffer[GetIndex(x - 1, y, z)].value); var bottom = y >= 1 && IsOpaque(voxelBuffer[GetIndex(x, y - 1, z)].value); var front = z >= 1 && IsOpaque(voxelBuffer[GetIndex(x, y, z - 1)].value); var right = x < ChunkSize - 1 && IsOpaque(voxelBuffer[GetIndex(x + 1, y, z)].value); var top = y < ChunkSize - 1 && IsOpaque(voxelBuffer[GetIndex(x, y + 1, z)].value); var back = z < ChunkSize - 1 && IsOpaque(voxelBuffer[GetIndex(x, y, z + 1)].value); face = new VisibleFacesBufferElement { west = left ? TextureID.AIR : TextureAtlas.GetFaceTexture(voxel, Direction.WEST), east = right ? TextureID.AIR : TextureAtlas.GetFaceTexture(voxel, Direction.EAST), down = bottom ? TextureID.AIR : TextureAtlas.GetFaceTexture(voxel, Direction.DOWN), up = top ? TextureID.AIR : TextureAtlas.GetFaceTexture(voxel, Direction.UP), north = front ? TextureID.AIR : TextureAtlas.GetFaceTexture(voxel, Direction.NORTH), south = back ? TextureID.AIR : TextureAtlas.GetFaceTexture(voxel, Direction.SOUTH), }; } visibleFacesBuffer[GetIndex(x, y, z)] = face; } } } // Mark as ready for render ecb.RemoveComponent <CalculateFacesTag>(entityInQueryIndex, e); ecb.AddComponent <CreateMeshChunkTag>(entityInQueryIndex, e); } ) .ScheduleParallel(); _commandsBuffer.AddJobHandleForProducer(Dependency); }