private bool ComputeNewVoxels(ComputeShader shader, ThreadedChunkLoader thread, Chunk chunk, Vector3 min, int octreeSize) { float gpuStart = Time.realtimeSinceStartup; float[] chunkPos = new float[3] { min.x, min.y, min.z }; shader.SetFloats("chunkPosition", chunkPos); shader.SetInt("resolution", octreeSize); shader.SetInt("octreeSize", octreeSize); int[] zero = new int[1] { 0 }; float sqRTRC = Mathf.Sqrt(octreeSize * octreeSize * octreeSize); int sqRTRes = (int)sqRTRC; if (sqRTRC > sqRTRes) { sqRTRes++; } int[] zeroSq = new int[sqRTRes]; for (int i = 0; i < sqRTRes; i++) { zeroSq[i] = 0; } ComputeBuffer Perm = new ComputeBuffer(512, sizeof(int)); Perm.SetData(permutations); ComputeBuffer cornCount = new ComputeBuffer(sqRTRes, sizeof(int)); ComputeBuffer finalCount = new ComputeBuffer(1, sizeof(int)); ComputeBuffer voxMatBuffer = new ComputeBuffer(octreeSize * octreeSize * octreeSize, sizeof(uint)); ComputeBuffer cornerMaterials = new ComputeBuffer((octreeSize + 1) * (octreeSize + 1) * (octreeSize + 1), sizeof(uint)); shader.SetInt("primitiveModCount", chunk.modCount); ComputeBuffer PrimMods = null; if (chunk.modCount > 0) { PrimMods = new ComputeBuffer(chunk.modCount, (sizeof(int) * 2) + (sizeof(float) * 6)); PrimMods.SetData(chunk.primitiveMods); } int kernel = shader.FindKernel("ComputeMaterials"); if (chunk.modCount > 0) { shader.SetBuffer(kernel, "primitiveMods", PrimMods); } shader.SetBuffer(kernel, "Perm", Perm); shader.SetBuffer(kernel, "cornerMaterials", cornerMaterials); shader.Dispatch(kernel, 1, 1, 1); kernel = shader.FindKernel("ComputeCorners"); shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer); shader.SetBuffer(kernel, "cornerCount", cornCount); shader.SetBuffer(kernel, "cornerMaterials", cornerMaterials); cornCount.SetData(zeroSq); shader.Dispatch(kernel, 1, 1, 1); kernel = shader.FindKernel("AddLength"); shader.SetBuffer(kernel, "cornerCount", cornCount); shader.SetBuffer(kernel, "finalCount", finalCount); finalCount.SetData(zero); shader.Dispatch(kernel, 1, 1, 1); int[] voxelCount = new int[1]; finalCount.GetData(voxelCount); int count = voxelCount[0]; if (count <= 0) { voxMatBuffer.Dispose(); cornerMaterials.Dispose(); cornCount.Dispose(); finalCount.Dispose(); Perm.Dispose(); if (chunk.modCount > 0) { PrimMods.Dispose(); PrimMods = null; } Perm = null; voxMatBuffer = null; cornerMaterials = null; cornCount = null; finalCount = null; return(false); } //Debug.Log (count); ComputeBuffer cornerIndexes = new ComputeBuffer(count, sizeof(uint)); kernel = shader.FindKernel("ComputePositions"); shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer); shader.SetBuffer(kernel, "cornerCount", cornCount); shader.SetBuffer(kernel, "cornerIndexes", cornerIndexes); shader.Dispatch(kernel, 1, 1, 1); ComputeBuffer voxBuffer = new ComputeBuffer(count, (sizeof(float) * 6) + sizeof(int)); ComputeBuffer positionBuffer = new ComputeBuffer(count, sizeof(float) * 3); kernel = shader.FindKernel("ComputeVoxels"); if (chunk.modCount > 0) { shader.SetBuffer(kernel, "primitiveMods", PrimMods); } shader.SetBuffer(kernel, "Perm", Perm); shader.SetBuffer(kernel, "voxMins", positionBuffer); shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer); shader.SetBuffer(kernel, "finalCount", finalCount); shader.SetBuffer(kernel, "cornerIndexes", cornerIndexes); shader.SetBuffer(kernel, "voxels", voxBuffer); shader.Dispatch(kernel, (count / 128) + 1, 1, 1); Vector3[] voxelMins = new Vector3[count]; positionBuffer.GetData(voxelMins); positionBuffer.Dispose(); positionBuffer = null; uint[] voxelMaterials = new uint[count]; cornerIndexes.GetData(voxelMaterials); cornerIndexes.Dispose(); cornerIndexes = null; GPUVOX[] voxs = new GPUVOX[count]; voxBuffer.GetData(voxs); voxBuffer.Dispose(); voxBuffer = null; voxMatBuffer.Dispose(); cornerMaterials.Dispose(); cornCount.Dispose(); finalCount.Dispose(); Perm.Dispose(); if (chunk.modCount > 0) { PrimMods.Dispose(); PrimMods = null; } Perm = null; voxMatBuffer = null; cornerMaterials = null; cornCount = null; finalCount = null; float gpuEnd = Time.realtimeSinceStartup; //Debug.Log ("GPU time on chunk: " + (gpuEnd - gpuStart)); thread.setData(this, count, voxelMins, voxelMaterials, voxs, min, octreeSize); thread.setChunkForUpdate(chunk); thread.Start(); return(true); }
private List <OctreeNode> ComputeVoxels(ComputeShader shader, Vector3 min, int octreeSize) { float gpuStart = Time.realtimeSinceStartup; float[] chunkPos = new float[3] { min.x, min.y, min.z }; shader.SetFloats("chunkPosition", chunkPos); shader.SetInt("resolution", octreeSize); shader.SetInt("octreeSize", octreeSize); float sqRTRC = Mathf.Sqrt(octreeSize * octreeSize * octreeSize); int sqRTRes = (int)sqRTRC; if (sqRTRC > sqRTRes) { sqRTRes++; } ComputeBuffer Perm = new ComputeBuffer(512, sizeof(int)); Perm.SetData(permutations); ComputeBuffer cornCount = new ComputeBuffer(sqRTRes, sizeof(int)); ComputeBuffer finalCount = new ComputeBuffer(1, sizeof(float)); ComputeBuffer voxMatBuffer = new ComputeBuffer(octreeSize * octreeSize * octreeSize, sizeof(uint)); float rD8 = octreeSize / 8.0f; int rD8I = (int)rD8; if (rD8 > rD8I) { rD8I++; } int kernel = shader.FindKernel("ComputeCorners"); shader.SetBuffer(kernel, "Perm", Perm); shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer); shader.Dispatch(kernel, rD8I, rD8I, rD8I); /*kernel = shader.FindKernel("ComputeLength"); * shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer); * shader.SetBuffer(kernel, "cornerCount", cornCount); * shader.Dispatch(kernel, 1, 1, 1);*/ kernel = shader.FindKernel("AddLength"); shader.SetBuffer(kernel, "cornerCount", cornCount); shader.SetBuffer(kernel, "finalCount", finalCount); shader.Dispatch(kernel, 1, 1, 1); float[] voxelCount = new float[1]; finalCount.GetData(voxelCount); finalCount.SetData(voxelCount); int count = (int)voxelCount[0]; //Debug.Log (count); if (count <= 0) { voxMatBuffer.Dispose(); cornCount.Dispose(); finalCount.Dispose(); Perm.Dispose(); return(null); } ComputeBuffer cornerIndexes = new ComputeBuffer(count, sizeof(uint)); kernel = shader.FindKernel("ComputePositions"); shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer); shader.SetBuffer(kernel, "cornerCount", cornCount); shader.SetBuffer(kernel, "cornerIndexes", cornerIndexes); shader.Dispatch(kernel, 1, 1, 1); ComputeBuffer voxBuffer = new ComputeBuffer(count, (sizeof(float) * 6) + sizeof(int)); ComputeBuffer positionBuffer = new ComputeBuffer(count, sizeof(float) * 3); kernel = shader.FindKernel("ComputeVoxels"); shader.SetBuffer(kernel, "Perm", Perm); shader.SetBuffer(kernel, "voxMins", positionBuffer); shader.SetBuffer(kernel, "voxelMaterials", voxMatBuffer); shader.SetBuffer(kernel, "finalCount", finalCount); shader.SetBuffer(kernel, "cornerIndexes", cornerIndexes); shader.SetBuffer(kernel, "voxels", voxBuffer); //int dispatchCount = count / 10; shader.Dispatch(kernel, (count / 128) + 1, 1, 1); List <OctreeNode> computedVoxels = new List <OctreeNode>(); Vector3[] voxelMins = new Vector3[count]; positionBuffer.GetData(voxelMins); positionBuffer.Dispose(); uint[] voxelMaterials = new uint[count]; cornerIndexes.GetData(voxelMaterials); cornerIndexes.Dispose(); GPUVOX[] voxs = new GPUVOX[count]; voxBuffer.GetData(voxs); voxBuffer.Dispose(); voxMatBuffer.Dispose(); cornCount.Dispose(); finalCount.Dispose(); Perm.Dispose(); float gpuEnd = Time.realtimeSinceStartup; //Debug.Log ("GPU time on chunk: " + (gpuEnd - gpuStart)); int HIGHEST_VOXEL_RES = 64; int voxelSize = HIGHEST_VOXEL_RES / octreeSize; for (int i = 0; i < count; i++) { if (voxs[i].numPoints != 0) { OctreeNode leaf = new OctreeNode(); leaf.type = OctreeNodeType.Node_Leaf; leaf.size = voxelSize; OctreeDrawInfo drawInfo = new OctreeDrawInfo(); drawInfo.position = voxs[i].vertPoint; drawInfo.averageNormal = voxs[i].avgNormal; drawInfo.corners = (int)voxelMaterials[i]; leaf.drawInfo = drawInfo; leaf.min = voxelMins[i]; computedVoxels.Add(leaf); } } //Debug.Log ("CPU Leaf generation time on chunk: " + (Time.realtimeSinceStartup - gpuEnd)); //Debug.Log (computedVoxels.Count); return(computedVoxels); }