bool TransparencyCheck(NativeSlice <Voxel> voxels, int3 gridPosition) { if (VoxelUtil.BoundaryCheck(gridPosition, chunkSize)) { return(voxels[VoxelUtil.To1DIndex(gridPosition, chunkSize)].data != Voxel.VoxelType.Air); } else { int3 worldGridPosition = gridPosition + chunkPosition * chunkSize; int3 neighborChunkPosition = VoxelUtil.WorldToChunk(worldGridPosition, chunkSize); if (neighborHashMap.TryGetValue(neighborChunkPosition, out int voxelIndex)) { if (voxelIndex == -1) { return(false); } int3 position = VoxelUtil.WorldToGrid(worldGridPosition, neighborChunkPosition, chunkSize); NativeSlice <Voxel> neighborVoxels = voxelsWithNeighbor.Slice(voxelIndex * chunkSize.x * chunkSize.y * chunkSize.z, chunkSize.x * chunkSize.y * chunkSize.z); return(neighborVoxels[VoxelUtil.To1DIndex(position, chunkSize)].data != Voxel.VoxelType.Air); } return(false); } }
public void Execute() { for (int x = 0; x < chunkSize.x; x++) { for (int y = 0; y < chunkSize.y; y++) { for (int z = 0; z < chunkSize.z; z++) { int3 gridPosition = new int3(x, y, z); int index = VoxelUtil.To1DIndex(gridPosition, chunkSize); Voxel voxel = voxels[index]; if (voxel.data == Voxel.VoxelType.Air) { continue; } for (int direction = 0; direction < 6; direction++) { int3 neighborPosition = gridPosition + VoxelUtil.VoxelDirectionOffsets[direction]; if (TransparencyCheck(voxels, neighborPosition, chunkSize)) { continue; } AddQuadByDirection(direction, voxel.data, lightData[index], 1.0f, 1.0f, gridPosition, counter.Increment(), vertices, normals, uvs, colors, indices); } } } } }
public static bool TransparencyCheck(NativeArray <Voxel> voxels, int3 position, int chunkSize) { if (!BoundaryCheck(chunkSize, position)) { return(false); } return(voxels[VoxelUtil.To1DIndex(position, chunkSize)].data != Voxel.VoxelType.Air); }
public void Execute(int index) { int3 gridPosition = VoxelUtil.To3DIndex(index, chunkSize); Voxel voxel = voxels[index]; if (voxel.data == Voxel.VoxelType.Air) { return; } for (int direction = 0; direction < 6; direction++) { int3 neighborPosition = gridPosition + VoxelDirectionOffsets[direction]; if (TransparencyCheck(voxels, neighborPosition, chunkSize)) { continue; } AddQuadByDirection(direction, voxel.data, lightData[index], 1.0f, 1.0f, gridPosition, counter, vertices, normals, uvs, colors, indices); } }
public unsafe void Execute(int index) { int3 gridPosition = VoxelUtil.To3DIndex(index, chunkSize); NativeSlice <Voxel> voxels = voxelsWithNeighbor.Slice(neighborHashMap[chunkPosition] * chunkSize.x * chunkSize.y * chunkSize.z, chunkSize.x * chunkSize.y * chunkSize.z); Voxel voxel = voxels[index]; VoxelLight voxelLight = new VoxelLight(); if (voxel.data == Voxel.VoxelType.Air) { lightDatas[index] = voxelLight; return; } for (int direction = 0; direction < 6; direction++) { // Todo : Code Cleanup!! int3 down = gridPosition; int3 left = gridPosition; int3 top = gridPosition; int3 right = gridPosition; int3 leftDownCorner = gridPosition; int3 topLeftCorner = gridPosition; int3 topRightCorner = gridPosition; int3 rightDownCorner = gridPosition; down[VoxelUtil.DirectionAlignedY[direction]] -= 1; left[VoxelUtil.DirectionAlignedX[direction]] -= 1; top[VoxelUtil.DirectionAlignedY[direction]] += 1; right[VoxelUtil.DirectionAlignedX[direction]] += 1; leftDownCorner[VoxelUtil.DirectionAlignedX[direction]] -= 1; leftDownCorner[VoxelUtil.DirectionAlignedY[direction]] -= 1; topLeftCorner[VoxelUtil.DirectionAlignedX[direction]] -= 1; topLeftCorner[VoxelUtil.DirectionAlignedY[direction]] += 1; topRightCorner[VoxelUtil.DirectionAlignedX[direction]] += 1; topRightCorner[VoxelUtil.DirectionAlignedY[direction]] += 1; rightDownCorner[VoxelUtil.DirectionAlignedX[direction]] += 1; rightDownCorner[VoxelUtil.DirectionAlignedY[direction]] -= 1; int3 *neighbors = stackalloc int3[] { down, leftDownCorner, left, topLeftCorner, top, topRightCorner, right, rightDownCorner }; for (int i = 0; i < 8; i++) { neighbors[i][VoxelUtil.DirectionAlignedZ[direction]] += VoxelUtil.DirectionAlignedSign[direction]; } for (int i = 0; i < 4; i++) { bool side1 = TransparencyCheck(voxels, neighbors[VoxelUtil.AONeighborOffsets[i * 3]]); bool corner = TransparencyCheck(voxels, neighbors[VoxelUtil.AONeighborOffsets[i * 3 + 1]]); bool side2 = TransparencyCheck(voxels, neighbors[VoxelUtil.AONeighborOffsets[i * 3 + 2]]); if (side1 && side2) { voxelLight.ambient[i + direction * 4] = 0f; } else { voxelLight.ambient[i + direction * 4] = ((side1 ? 0f : 1f) + (side2 ? 0f : 1f) + (corner ? 0f : 1f)) / 3.0f; } } } lightDatas[index] = voxelLight; }
public void Execute() { NativeHashMap <int3, Empty> hashMap = new NativeHashMap <int3, Empty>(chunkSize * chunkSize, Allocator.Temp); for (int direction = 0; direction < 6; direction++) { for (int depth = 0; depth < chunkSize; depth++) { for (int x = 0; x < chunkSize; x++) { for (int y = 0; y < chunkSize;) { int3 gridPosition = new int3 { [DirectionAlignedX[direction]] = x, [DirectionAlignedY[direction]] = y, [DirectionAlignedZ[direction]] = depth }; Voxel voxel = voxels[VoxelUtil.To1DIndex(gridPosition, chunkSize)]; if (voxel.data == Voxel.VoxelType.Air) { y++; continue; } if (hashMap.ContainsKey(gridPosition)) { y++; continue; } int3 neighborPosition = gridPosition + VoxelDirectionOffsets[direction]; if (TransparencyCheck(voxels, neighborPosition, chunkSize)) { y++; continue; } VoxelLight light = lightData[VoxelUtil.To1DIndex(gridPosition, chunkSize)]; hashMap.TryAdd(gridPosition, new Empty()); int height; for (height = 1; height + y < chunkSize; height++) { int3 nextPosition = gridPosition; nextPosition[DirectionAlignedY[direction]] += height; Voxel nextVoxel = voxels[VoxelUtil.To1DIndex(nextPosition, chunkSize)]; VoxelLight nextLight = lightData[VoxelUtil.To1DIndex(nextPosition, chunkSize)]; if (nextVoxel.data != voxel.data) { break; } if (!nextLight.CompareFace(light, direction)) { break; } if (hashMap.ContainsKey(nextPosition)) { break; } hashMap.TryAdd(nextPosition, new Empty()); } bool isDone = false; int width; for (width = 1; width + x < chunkSize; width++) { for (int dy = 0; dy < height; dy++) { int3 nextPosition = gridPosition; nextPosition[DirectionAlignedX[direction]] += width; nextPosition[DirectionAlignedY[direction]] += dy; Voxel nextVoxel = voxels[VoxelUtil.To1DIndex(nextPosition, chunkSize)]; VoxelLight nextLight = lightData[VoxelUtil.To1DIndex(nextPosition, chunkSize)]; if (nextVoxel.data != voxel.data || hashMap.ContainsKey(nextPosition) || !nextLight.CompareFace(light, direction)) { isDone = true; break; } } if (isDone) { break; } for (int dy = 0; dy < height; dy++) { int3 nextPosition = gridPosition; nextPosition[DirectionAlignedX[direction]] += width; nextPosition[DirectionAlignedY[direction]] += dy; hashMap.TryAdd(nextPosition, new Empty()); } } AddQuadByDirection(direction, voxel.data, light, width, height, gridPosition, counter, vertices, normals, uvs, colors, indices); y += height; } } hashMap.Clear(); } } hashMap.Dispose(); }
public void Execute() { for (int direction = 0; direction < 6; direction++) { for (int depth = 0; depth < chunkSize; depth++) { for (int x = 0; x < chunkSize; x++) { for (int y = 0; y < chunkSize;) { int3 gridPosition = new int3 { [DirectionAlignedX[direction]] = x, [DirectionAlignedY[direction]] = y, [DirectionAlignedZ[direction]] = depth }; int index = VoxelUtil.To1DIndex(gridPosition, chunkSize); Voxel voxel = voxels[index]; VoxelLight light = lightData[index]; if (voxel.data == Voxel.VoxelType.Air) { y++; continue; } int3 neighborPosition = gridPosition + VoxelDirectionOffsets[direction]; if (TransparencyCheck(voxels, neighborPosition, chunkSize)) { y++; continue; } int height; for (height = 1; height + y < chunkSize; height++) { int3 nextPosition = gridPosition; nextPosition[DirectionAlignedY[direction]] += height; int nextIndex = VoxelUtil.To1DIndex(nextPosition, chunkSize); Voxel nextVoxel = voxels[nextIndex]; VoxelLight nextLight = lightData[nextIndex]; if (nextVoxel.data != voxel.data) { break; } if (!light.CompareFace(nextLight, direction)) { break; } } AddQuadByDirection(direction, voxel.data, light, 1.0f, height, gridPosition, counter, vertices, normals, uvs, colors, indices); y += height; } } } } }
public unsafe void Execute(int index) { int3 gridPosition = VoxelUtil.To3DIndex(index, chunkSize); Voxel voxel = voxels[index]; VoxelLight voxelLight = new VoxelLight(); if (voxel.data == Voxel.VoxelType.Air) { lightDatas[index] = voxelLight; return; } for (int direction = 0; direction < 6; direction++) { int3 neighborPosition = gridPosition + VoxelMeshBuilder.VoxelDirectionOffsets[direction]; if (VoxelMeshBuilder.TransparencyCheck(voxels, neighborPosition, chunkSize)) { continue; } // Todo : Code Cleanup!! int3 down = gridPosition; int3 left = gridPosition; int3 top = gridPosition; int3 right = gridPosition; int3 leftDownCorner = gridPosition; int3 topLeftCorner = gridPosition; int3 topRightCorner = gridPosition; int3 rightDownCorner = gridPosition; down[VoxelMeshBuilder.DirectionAlignedY[direction]] -= 1; left[VoxelMeshBuilder.DirectionAlignedX[direction]] -= 1; top[VoxelMeshBuilder.DirectionAlignedY[direction]] += 1; right[VoxelMeshBuilder.DirectionAlignedX[direction]] += 1; leftDownCorner[VoxelMeshBuilder.DirectionAlignedX[direction]] -= 1; leftDownCorner[VoxelMeshBuilder.DirectionAlignedY[direction]] -= 1; topLeftCorner[VoxelMeshBuilder.DirectionAlignedX[direction]] -= 1; topLeftCorner[VoxelMeshBuilder.DirectionAlignedY[direction]] += 1; topRightCorner[VoxelMeshBuilder.DirectionAlignedX[direction]] += 1; topRightCorner[VoxelMeshBuilder.DirectionAlignedY[direction]] += 1; rightDownCorner[VoxelMeshBuilder.DirectionAlignedX[direction]] += 1; rightDownCorner[VoxelMeshBuilder.DirectionAlignedY[direction]] -= 1; int3 *neighbors = stackalloc int3[] { down, leftDownCorner, left, topLeftCorner, top, topRightCorner, right, rightDownCorner }; for (int i = 0; i < 8; i++) { neighbors[i][VoxelMeshBuilder.DirectionAlignedZ[direction]] += (direction % 2 == 0) ? 1 : -1; } for (int i = 0; i < 4; i++) { bool side1 = VoxelMeshBuilder.TransparencyCheck(voxels, neighbors[AONeighborOffsets[i * 3]], chunkSize); bool corner = VoxelMeshBuilder.TransparencyCheck(voxels, neighbors[AONeighborOffsets[i * 3 + 1]], chunkSize); bool side2 = VoxelMeshBuilder.TransparencyCheck(voxels, neighbors[AONeighborOffsets[i * 3 + 2]], chunkSize); if (side1 && side2) { voxelLight.ambient[i + direction * 4] = 0f; } else { voxelLight.ambient[i + direction * 4] = ((side1 ? 0 : 1) + (side2 ? 0 : 1) + (corner ? 0 : 1)) / 3.0f; } } } lightDatas[index] = voxelLight; }