public ComputeBuffer Result(int chunkCoordX, int chunkCoordY, int chunkCoordZ, int cubesPerAxis, ref FragRegionIndex fragRegionIndex) { //Total number of cubes inside a chunk int cubesPerChunk = cubesPerAxis * cubesPerAxis * cubesPerAxis; int indexesPerChunk = cubesPerAxis * cubesPerAxis; //How many to process on a single thread int processPerThread = Mathf.CeilToInt(cubesPerAxis / 8.0f); //RWStructuredBuffer sets ComputeBuffer voxelsBuffer = new ComputeBuffer(cubesPerChunk, GPUVoxel.Stride); ComputeBuffer fragRegionIndexsBuffer = new ComputeBuffer(indexesPerChunk, Stride.IntStride); NoiseShader.SetBuffer(Kernel, "Voxels", voxelsBuffer); NoiseShader.SetBuffer(Kernel, "RegionIndexes", fragRegionIndexsBuffer); //Sets NoiseShader.SetInts("ChunkCoord", new int[3] { chunkCoordX, chunkCoordY, chunkCoordZ }); //Run kernal NoiseShader.Dispatch(Kernel, processPerThread, processPerThread, processPerThread); //Output int[] fragRegionIndexOutput = new int[indexesPerChunk]; fragRegionIndexsBuffer.GetData(fragRegionIndexOutput); //Process indexes for fragment shader for (int i = 0; i < fragRegionIndexOutput.Length; i++) { if (fragRegionIndex.Index0 == fragRegionIndexOutput[i]) { continue; } if (fragRegionIndex.Index0 == -1) { fragRegionIndex.Index0 = fragRegionIndexOutput[i]; continue; } if (fragRegionIndex.Index1 == fragRegionIndexOutput[i]) { continue; } if (fragRegionIndex.Index1 == -1) { fragRegionIndex.Index1 = fragRegionIndexOutput[i]; continue; } if (fragRegionIndex.Index2 == fragRegionIndexOutput[i]) { continue; } if (fragRegionIndex.Index2 == -1) { fragRegionIndex.Index2 = fragRegionIndexOutput[i]; continue; } if (fragRegionIndex.Index3 == fragRegionIndexOutput[i]) { continue; } if (fragRegionIndex.Index3 == -1) { fragRegionIndex.Index3 = fragRegionIndexOutput[i]; break; } } //Get rid of buffer data fragRegionIndexsBuffer.Dispose(); return(voxelsBuffer); }
public (Vector3[], int[], FragRegionIndex) Result(int chunkCoordX, int chunkCoordY, int chunkCoordZ, int cubesPerAxis, VoxelNoiseGenerator noiseGenerator) { int chunkOffsetX = chunkCoordX * 3; int chunkOffsetY = chunkCoordY * 3; int chunkOffsetZ = chunkCoordZ * 3; int maxRectangleGPUCount = (cubesPerAxis * cubesPerAxis * cubesPerAxis) * 5; //How many to process on a single thread int processPerThread = Mathf.CeilToInt(cubesPerAxis / 8.0f); //RWStructuredBuffer sets ComputeBuffer rectanglesBuffer = new ComputeBuffer(maxRectangleGPUCount, GPURectangle.Stride, ComputeBufferType.Append); ComputeBuffer rectCountBuffer = new ComputeBuffer(1, Stride.IntStride, ComputeBufferType.Raw); rectanglesBuffer.SetCounterValue(0); FragRegionIndex fragRegionIndex = new FragRegionIndex { Index0 = -1, Index1 = -1, Index2 = -1, Index3 = -1, }; //Generate sub chunks to combine into a whole chunk for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { for (int z = 0; z < 3; z++) { //Run noise kernal ComputeBuffer noiseShader = noiseGenerator.Result(chunkOffsetX + x, chunkOffsetY + y, chunkOffsetZ + z, cubesPerAxis, ref fragRegionIndex); //Run face kernal FaceLeftGenerator.Result(new Vector3Int(x, y, z), new Vector3Int(processPerThread, 1, 1), noiseShader, rectanglesBuffer); FaceForwardGenerator.Result(new Vector3Int(x, y, z), new Vector3Int(1, 1, processPerThread), noiseShader, rectanglesBuffer); FaceRightGenerator.Result(new Vector3Int(x, y, z), new Vector3Int(processPerThread, 1, 1), noiseShader, rectanglesBuffer); FaceBackwardGenerator.Result(new Vector3Int(x, y, z), new Vector3Int(1, 1, processPerThread), noiseShader, rectanglesBuffer); FaceUpGenerator.Result(new Vector3Int(x, y, z), new Vector3Int(1, processPerThread, 1), noiseShader, rectanglesBuffer); FaceDownGenerator.Result(new Vector3Int(x, y, z), new Vector3Int(1, processPerThread, 1), noiseShader, rectanglesBuffer); //Get rid of buffer data noiseShader.Dispose(); } } } //Grab output count ComputeBuffer.CopyCount(rectanglesBuffer, rectCountBuffer, 0); int[] rectCount = { 0 }; rectCountBuffer.GetData(rectCount); //Outputs GPURectangle[] rectangleGPUOutput = new GPURectangle[rectCount[0]]; Vector3[] verticesOutput = new Vector3[rectangleGPUOutput.Length * 4]; int[] trianglesOutput = new int[rectangleGPUOutput.Length * 6]; //Grab outputs rectanglesBuffer.GetData(rectangleGPUOutput, 0, 0, rectCount[0]); //Get rid of buffer data rectanglesBuffer.Dispose(); rectCountBuffer.Dispose(); //Process triangles for (int i = 0; i < rectangleGPUOutput.Length; i++) { int vertIndex = i * 4; int triIndex = i * 6; //Vertices verticesOutput[vertIndex] = rectangleGPUOutput[i].VertexA; verticesOutput[vertIndex + 1] = rectangleGPUOutput[i].VertexB; verticesOutput[vertIndex + 2] = rectangleGPUOutput[i].VertexC; verticesOutput[vertIndex + 3] = rectangleGPUOutput[i].VertexD; //Triangles trianglesOutput[triIndex] = vertIndex; trianglesOutput[triIndex + 1] = vertIndex + 1; trianglesOutput[triIndex + 2] = vertIndex + 2; trianglesOutput[triIndex + 3] = vertIndex + 2; trianglesOutput[triIndex + 4] = vertIndex + 3; trianglesOutput[triIndex + 5] = vertIndex; } return(verticesOutput, trianglesOutput, fragRegionIndex); }