private void Generate(ComputeShader computePositionWeight, int width, int height, int depth) { int count = width * height * depth; int widthD = width - 1; int heightD = height - 1; int depthD = depth - 1; int countD = widthD * heightD * depthD; int nearestW = NearestPowerOfTwo(widthD); int nearestH = NearestPowerOfTwo(heightD); int nearestD = NearestPowerOfTwo(depthD); int nearestCount = nearestW * nearestH * nearestD; Vector3 gridDim = new Vector3((float)Math.Ceiling(width / 8.0f), (float)Math.Ceiling(height / 8.0f), (float)Math.Ceiling(depth / 8.0f)); Vector3 gridDimD = new Vector3((float)Math.Ceiling(widthD / 8.0f), (float)Math.Ceiling(heightD / 8.0f), (float)Math.Ceiling(depthD / 8.0f)); constantBufferContainer = new DirectComputeConstantBuffer() { Width = 16, Height = 16, Depth = 16, Seed = (int)DateTime.Now.Ticks }; DirectComputeNoiseCube noiseCube = new DirectComputeNoiseCube(graphicsDevice); ShaderResourceView noiseSRV = noiseCube.GenerateNoiseTexture(constantBuffer, constantBufferContainer); Buffer voxelsBuffer = new Buffer(graphicsDevice, new BufferDescription() { BindFlags = BindFlags.UnorderedAccess, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.StructuredBuffer, Usage = ResourceUsage.Default, SizeInBytes = Marshal.SizeOf(typeof(Voxel)) * count, StructureByteStride = Marshal.SizeOf(typeof(Voxel)) }); UnorderedAccessView voxelsUAV = new UnorderedAccessView(graphicsDevice, voxelsBuffer); constantBufferContainer = new DirectComputeConstantBuffer() { Width = width, Height = height, Depth = depth, AmbientRayWidth = container.Settings.AmbientRayWidth, AmbientSamplesCount = container.Settings.AmbientSamplesCount, NearestWidth = nearestW, NearestHeight = nearestH, NearestDepth = nearestD }; DataBox data = graphicsDevice.ImmediateContext.MapSubresource(constantBuffer, MapMode.WriteDiscard, MapFlags.None); data.Data.Write <DirectComputeConstantBuffer>(constantBufferContainer); graphicsDevice.ImmediateContext.UnmapSubresource(constantBuffer, 0); graphicsDevice.ImmediateContext.ComputeShader.Set(computePositionWeight); graphicsDevice.ImmediateContext.ComputeShader.SetConstantBuffer(constantBuffer, 0); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(voxelsUAV, 0); graphicsDevice.ImmediateContext.ComputeShader.SetShaderResource(noiseSRV, 0); graphicsDevice.ImmediateContext.Dispatch((int)gridDim.X, (int)gridDim.Y, (int)gridDim.Z); graphicsDevice.ImmediateContext.ComputeShader.Set(computeNormalAmbient); graphicsDevice.ImmediateContext.Dispatch((int)gridDim.X, (int)gridDim.Y, (int)gridDim.Z); Buffer offsetsBuffer = new Buffer(graphicsDevice, new BufferDescription() { BindFlags = BindFlags.UnorderedAccess, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.StructuredBuffer, Usage = ResourceUsage.Default, SizeInBytes = Marshal.SizeOf(typeof(int)) * countD, StructureByteStride = Marshal.SizeOf(typeof(int)) }); UnorderedAccessView offsetsUAV = new UnorderedAccessView(graphicsDevice, offsetsBuffer); Buffer trisCountBuffer = new Buffer(graphicsDevice, new BufferDescription() { BindFlags = BindFlags.UnorderedAccess, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.StructuredBuffer, Usage = ResourceUsage.Default, SizeInBytes = Marshal.SizeOf(typeof(int)) * nearestCount, StructureByteStride = Marshal.SizeOf(typeof(int)) }); UnorderedAccessView trisCountUAV = new UnorderedAccessView(graphicsDevice, trisCountBuffer); graphicsDevice.ImmediateContext.ClearUnorderedAccessView(trisCountUAV, new int[] { 0, 0, 0, 0 }); graphicsDevice.ImmediateContext.ComputeShader.Set(computeMarchingCubesCases); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(offsetsUAV, 1); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(trisCountUAV, 2); graphicsDevice.ImmediateContext.Dispatch((int)gridDimD.X, (int)gridDimD.Y, (int)gridDimD.Z); UnorderedAccessView prefixSumsUAV = prefixScan.PrefixSumArray(constantBuffer, trisCountUAV); int lastTrisCount = DirectComputeBufferHelper.CopyBuffer <int>(graphicsDevice, trisCountBuffer, nearestCount - 1, 1)[0]; int lastPrefixSum = DirectComputeBufferHelper.CopyBuffer <int>(graphicsDevice, prefixSumsUAV.Resource, nearestCount - 1, 1)[0]; int totalVerticesCount = (lastTrisCount + lastPrefixSum) * 3; if (totalVerticesCount > 0) { if (container.Geometry != null) { container.Geometry.Dispose(); } container.VertexCount = totalVerticesCount; container.Geometry = new Buffer(graphicsDevice, new BufferDescription() { BindFlags = BindFlags.VertexBuffer, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None, SizeInBytes = Marshal.SizeOf(typeof(VoxelMeshVertex)) * totalVerticesCount, Usage = ResourceUsage.Default }); Buffer verticesBuffer = new Buffer(graphicsDevice, new BufferDescription() { BindFlags = BindFlags.UnorderedAccess, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.StructuredBuffer, Usage = ResourceUsage.Default, SizeInBytes = Marshal.SizeOf(typeof(VoxelMeshVertex)) * totalVerticesCount, StructureByteStride = Marshal.SizeOf(typeof(VoxelMeshVertex)) }); UnorderedAccessView verticesUAV = new UnorderedAccessView(graphicsDevice, verticesBuffer); constantBufferContainer = new DirectComputeConstantBuffer() { Width = width, Height = height, Depth = depth, NearestWidth = nearestW, NearestHeight = nearestH, NearestDepth = nearestD }; data = graphicsDevice.ImmediateContext.MapSubresource(constantBuffer, MapMode.WriteDiscard, MapFlags.None); data.Data.Write <DirectComputeConstantBuffer>(constantBufferContainer); graphicsDevice.ImmediateContext.UnmapSubresource(constantBuffer, 0); graphicsDevice.ImmediateContext.ComputeShader.Set(computeMarchingCubesVertices); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(trisCountUAV, 2); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(prefixSumsUAV, 3); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(verticesUAV, 5); graphicsDevice.ImmediateContext.Dispatch((int)gridDimD.X, (int)gridDimD.Y, (int)gridDimD.Z); graphicsDevice.ImmediateContext.CopyResource(verticesBuffer, container.Geometry); verticesUAV.Dispose(); verticesBuffer.Dispose(); } else { container.VertexCount = 0; if (container.Geometry != null) { container.Geometry.Dispose(); } } for (int i = 0; i <= 5; i++) { graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(null, i); } prefixSumsUAV.Resource.Dispose(); prefixSumsUAV.Dispose(); noiseCube.Dispose(); noiseSRV.Resource.Dispose(); noiseSRV.Dispose(); voxelsBuffer.Dispose(); voxelsUAV.Dispose(); offsetsBuffer.Dispose(); offsetsUAV.Dispose(); trisCountBuffer.Dispose(); trisCountUAV.Dispose(); }
private void Generate(ComputeShader computePositionWeight, int width, int height, int depth) { int count = width * height * depth; int widthD = width - 1; int heightD = height - 1; int depthD = depth - 1; int countD = widthD * heightD * depthD; int nearestW = NearestPowerOfTwo(widthD); int nearestH = NearestPowerOfTwo(heightD); int nearestD = NearestPowerOfTwo(depthD); int nearestCount = nearestW * nearestH * nearestD; Vector3 gridDim = new Vector3((float)Math.Ceiling(width / 8.0f), (float)Math.Ceiling(height / 8.0f), (float)Math.Ceiling(depth / 8.0f)); Vector3 gridDimD = new Vector3((float)Math.Ceiling(widthD / 8.0f), (float)Math.Ceiling(heightD / 8.0f), (float)Math.Ceiling(depthD / 8.0f)); constantBufferContainer = new DirectComputeConstantBuffer() { Width = 16, Height = 16, Depth = 16, Seed = (int)DateTime.Now.Ticks }; DirectComputeNoiseCube noiseCube = new DirectComputeNoiseCube(graphicsDevice); ShaderResourceView noiseSRV = noiseCube.GenerateNoiseTexture(constantBuffer, constantBufferContainer); Buffer voxelsBuffer = new Buffer(graphicsDevice, new BufferDescription() { BindFlags = BindFlags.UnorderedAccess, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.StructuredBuffer, Usage = ResourceUsage.Default, SizeInBytes = Marshal.SizeOf(typeof(Voxel)) * count, StructureByteStride = Marshal.SizeOf(typeof(Voxel)) }); UnorderedAccessView voxelsUAV = new UnorderedAccessView(graphicsDevice, voxelsBuffer); constantBufferContainer = new DirectComputeConstantBuffer() { Width = width, Height = height, Depth = depth, AmbientRayWidth = container.Settings.AmbientRayWidth, AmbientSamplesCount = container.Settings.AmbientSamplesCount, NearestWidth = nearestW, NearestHeight = nearestH, NearestDepth = nearestD }; DataBox data = graphicsDevice.ImmediateContext.MapSubresource(constantBuffer, MapMode.WriteDiscard, MapFlags.None); data.Data.Write<DirectComputeConstantBuffer>(constantBufferContainer); graphicsDevice.ImmediateContext.UnmapSubresource(constantBuffer, 0); graphicsDevice.ImmediateContext.ComputeShader.Set(computePositionWeight); graphicsDevice.ImmediateContext.ComputeShader.SetConstantBuffer(constantBuffer, 0); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(voxelsUAV, 0); graphicsDevice.ImmediateContext.ComputeShader.SetShaderResource(noiseSRV, 0); graphicsDevice.ImmediateContext.Dispatch((int)gridDim.X, (int)gridDim.Y, (int)gridDim.Z); graphicsDevice.ImmediateContext.ComputeShader.Set(computeNormalAmbient); graphicsDevice.ImmediateContext.Dispatch((int)gridDim.X, (int)gridDim.Y, (int)gridDim.Z); Buffer offsetsBuffer = new Buffer(graphicsDevice, new BufferDescription() { BindFlags = BindFlags.UnorderedAccess, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.StructuredBuffer, Usage = ResourceUsage.Default, SizeInBytes = Marshal.SizeOf(typeof(int)) * countD, StructureByteStride = Marshal.SizeOf(typeof(int)) }); UnorderedAccessView offsetsUAV = new UnorderedAccessView(graphicsDevice, offsetsBuffer); Buffer trisCountBuffer = new Buffer(graphicsDevice, new BufferDescription() { BindFlags = BindFlags.UnorderedAccess, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.StructuredBuffer, Usage = ResourceUsage.Default, SizeInBytes = Marshal.SizeOf(typeof(int)) * nearestCount, StructureByteStride = Marshal.SizeOf(typeof(int)) }); UnorderedAccessView trisCountUAV = new UnorderedAccessView(graphicsDevice, trisCountBuffer); graphicsDevice.ImmediateContext.ClearUnorderedAccessView(trisCountUAV, new int[] { 0, 0, 0, 0 }); graphicsDevice.ImmediateContext.ComputeShader.Set(computeMarchingCubesCases); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(offsetsUAV, 1); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(trisCountUAV, 2); graphicsDevice.ImmediateContext.Dispatch((int)gridDimD.X, (int)gridDimD.Y, (int)gridDimD.Z); UnorderedAccessView prefixSumsUAV = prefixScan.PrefixSumArray(constantBuffer, trisCountUAV); int lastTrisCount = DirectComputeBufferHelper.CopyBuffer<int>(graphicsDevice, trisCountBuffer, nearestCount - 1, 1)[0]; int lastPrefixSum = DirectComputeBufferHelper.CopyBuffer<int>(graphicsDevice, prefixSumsUAV.Resource, nearestCount - 1, 1)[0]; int totalVerticesCount = (lastTrisCount + lastPrefixSum) * 3; if (totalVerticesCount > 0) { if (container.Geometry != null) container.Geometry.Dispose(); container.VertexCount = totalVerticesCount; container.Geometry = new Buffer(graphicsDevice, new BufferDescription() { BindFlags = BindFlags.VertexBuffer, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None, SizeInBytes = Marshal.SizeOf(typeof(VoxelMeshVertex)) * totalVerticesCount, Usage = ResourceUsage.Default }); Buffer verticesBuffer = new Buffer(graphicsDevice, new BufferDescription() { BindFlags = BindFlags.UnorderedAccess, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.StructuredBuffer, Usage = ResourceUsage.Default, SizeInBytes = Marshal.SizeOf(typeof(VoxelMeshVertex)) * totalVerticesCount, StructureByteStride = Marshal.SizeOf(typeof(VoxelMeshVertex)) }); UnorderedAccessView verticesUAV = new UnorderedAccessView(graphicsDevice, verticesBuffer); constantBufferContainer = new DirectComputeConstantBuffer() { Width = width, Height = height, Depth = depth, NearestWidth = nearestW, NearestHeight = nearestH, NearestDepth = nearestD }; data = graphicsDevice.ImmediateContext.MapSubresource(constantBuffer, MapMode.WriteDiscard, MapFlags.None); data.Data.Write<DirectComputeConstantBuffer>(constantBufferContainer); graphicsDevice.ImmediateContext.UnmapSubresource(constantBuffer, 0); graphicsDevice.ImmediateContext.ComputeShader.Set(computeMarchingCubesVertices); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(trisCountUAV, 2); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(prefixSumsUAV, 3); graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(verticesUAV, 5); graphicsDevice.ImmediateContext.Dispatch((int)gridDimD.X, (int)gridDimD.Y, (int)gridDimD.Z); graphicsDevice.ImmediateContext.CopyResource(verticesBuffer, container.Geometry); verticesUAV.Dispose(); verticesBuffer.Dispose(); } else { container.VertexCount = 0; if (container.Geometry != null) container.Geometry.Dispose(); } for (int i = 0; i <= 5; i++) { graphicsDevice.ImmediateContext.ComputeShader.SetUnorderedAccessView(null, i); } prefixSumsUAV.Resource.Dispose(); prefixSumsUAV.Dispose(); noiseCube.Dispose(); noiseSRV.Resource.Dispose(); noiseSRV.Dispose(); voxelsBuffer.Dispose(); voxelsUAV.Dispose(); offsetsBuffer.Dispose(); offsetsUAV.Dispose(); trisCountBuffer.Dispose(); trisCountUAV.Dispose(); }