public bool CompareFace(VoxelLight other, int direction) { for (int i = 0; i < 4; i++) { if (ambient[direction * 4 + i] != other.ambient[direction * 4 + i]) { return(false); } } return(true); }
static unsafe void AddQuadByDirection(int direction, Voxel.VoxelType data, VoxelLight voxelLight, float width, float height, int3 gridPosition, NativeCounter.Concurrent counter, NativeArray <float3> vertices, NativeArray <float3> normals, NativeArray <float4> uvs, NativeArray <Color> colors, NativeArray <int> indices) { int numFace = counter.Increment(); int numVertices = numFace * 4; for (int i = 0; i < 4; i++) { float3 vertex; vertex = CubeVertices[CubeFaces[i + direction * 4]]; vertex[DirectionAlignedX[direction]] *= width; vertex[DirectionAlignedY[direction]] *= height; int atlasIndex = (int)data * 6 + direction; int2 atlasPosition = new int2 { x = atlasIndex % AtlasSize.x, y = atlasIndex / AtlasSize.x }; float4 uv = new float4 { x = CubeUVs[i].x * width, y = CubeUVs[i].y * height, z = atlasPosition.x, w = atlasPosition.y }; colors[numVertices + i] = new Color(0, 0, 0, voxelLight.ambient[i + direction * 4]); vertices[numVertices + i] = vertex + gridPosition; normals[numVertices + i] = VoxelDirectionOffsets[direction]; uvs[numVertices + i] = uv; } int numindices = numFace * 6; for (int i = 0; i < 6; i++) { if (voxelLight.ambient[direction * 4] + voxelLight.ambient[direction * 4 + 3] < voxelLight.ambient[direction * 4 + 1] + voxelLight.ambient[direction * 4 + 2]) { indices[numindices + i] = CubeFlipedIndices[direction * 6 + i] + numVertices; } else { indices[numindices + i] = CubeIndices[direction * 6 + i] + numVertices; } } }
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; }