void ExportMesh() { #if UNITY_EDITOR Vertex[] points = new Vertex[_Mesh.vertices.Length]; _GraphicsBuffer.GetData(points); Mesh mesh = new Mesh(); mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; List <Vector3> vertices = new List <Vector3>(); List <int> triangles = new List <int>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <Vector4> tangents = new List <Vector4>(); for (int i = 0; i < points.Length; i++) { vertices.Add(points[i].Position); triangles.Add(i); normals.Add(points[i].Normal); tangents.Add(points[i].Tangent); uvs.Add(points[i].Texcoord); } mesh.vertices = vertices.ToArray(); mesh.triangles = triangles.ToArray(); mesh.normals = normals.ToArray(); mesh.tangents = tangents.ToArray(); mesh.uv = uvs.ToArray(); string fileName = System.Guid.NewGuid().ToString("N"); UnityEditor.AssetDatabase.CreateAsset(mesh, "Assets/" + fileName + ".asset"); GameObject target = new GameObject(); target.name = fileName; target.AddComponent <MeshFilter>().sharedMesh = mesh; MeshRenderer renderer = target.AddComponent <MeshRenderer>(); renderer.sharedMaterial = UnityEditor.AssetDatabase.GetBuiltinExtraResource <Material>("Default-Material.mat"); UnityEditor.PrefabUtility.SaveAsPrefabAsset(target, "Assets/" + fileName + ".prefab"); #endif }
public static string GenerateBufferHash <T>(GraphicsBuffer buffer) where T : struct { var count = buffer.count; var datas = new T[count]; buffer.GetData(datas); return(GenerateBufferHash(count, datas)); }
public static async Task RunAsync(GraphicsDevice device) { int count = 100; int sumCount = 10; List <Task> tasks = new List <Task>(); for (int i = 0; i < count; i++) { int index = i; Console.WriteLine($"Scheduling task {index}"); tasks.Add(Task.Run(async() => { GraphicsBuffer <float> buffer = GraphicsBuffer.Create <float>(device, sumCount, ResourceFlags.AllowUnorderedAccess); TestShader shader = new TestShader(buffer, Sigmoid); ShaderGeneratorContext context = new ShaderGeneratorContext(device); context.Visit(shader); ShaderGeneratorResult result = new ShaderGenerator(shader).GenerateShader(); PipelineState pipelineState = await context.CreateComputePipelineStateAsync(); DescriptorSet?descriptorSet = context.CreateShaderResourceViewDescriptorSet(); using (CommandList commandList = new CommandList(device, CommandListType.Compute)) { commandList.SetPipelineState(pipelineState); if (descriptorSet != null) { commandList.SetComputeRootDescriptorTable(0, descriptorSet); } commandList.Dispatch(1, 1, 1); await commandList.FlushAsync(); } float sum = buffer.GetData().Sum(); Console.WriteLine($"Thread: {index}, sum: {sum}."); })); } Console.WriteLine("Awaiting tasks..."); Console.WriteLine($"Task count: {tasks.Count}"); await Task.WhenAll(tasks); Console.WriteLine("DONE!"); }
int GetBufferCount(GraphicsBuffer buffer) { if (buffer == null || buffer == CounterBuffer) { return(0); } GraphicsBuffer.CopyCount(buffer, CounterBuffer, 0); int[] counter = new int[1]; CounterBuffer.GetData(counter); return(counter[0]); }
int Decode(Texture source) { Shader.SetTexture(kernelIndex_, "Source", source); Shader.SetInt("Row", Row); Shader.SetInt("Column", Column); Shader.SetBuffer(kernelIndex_, "Result", readbackBuffer_); Shader.Dispatch(kernelIndex_, Row, Column, 1); readbackBuffer_.GetData(data_); int value = 0; for (int i = 0; i < data_.Length; i++) { if (data_[i].grayscale > 0.5) { value += 1 << i; } } return(value); }
private static async Task Main() { // Create graphics device using GraphicsDevice device = new GraphicsDevice(FeatureLevel.Level11_0); // Create graphics buffer int width = 10; int height = 10; float[] array = new float[width * height]; for (int i = 0; i < array.Length; i++) { array[i] = i; } float[] outputArray = new float[width * height]; using GraphicsBuffer <float> sourceBuffer = GraphicsBuffer.ShaderResource.New(device, array.AsSpan()); using GraphicsBuffer <float> destinationBuffer = GraphicsBuffer.UnorderedAccess.New <float>(device, array.Length * 2); GraphicsBuffer <float> slicedDestinationBuffer = destinationBuffer.Slice(20, 60); slicedDestinationBuffer = slicedDestinationBuffer.Slice(10, 50); DescriptorSet descriptorSet = new DescriptorSet(device, 2); descriptorSet.AddUnorderedAccessViews(slicedDestinationBuffer); descriptorSet.AddShaderResourceViews(sourceBuffer); // Generate computer shader bool generateWithDelegate = true; ShaderGenerator shaderGenerator = generateWithDelegate ? CreateShaderGeneratorWithDelegate(sourceBuffer, destinationBuffer) : CreateShaderGeneratorWithClass(); ShaderGeneratorResult result = shaderGenerator.GenerateShader(); // Copmile shader byte[] shaderBytecode = ShaderCompiler.Compile(DxcShaderStage.ComputeShader, result.ShaderSource, result.EntryPoints["compute"]); DescriptorRange1[] descriptorRanges = new DescriptorRange1[] { new DescriptorRange1(DescriptorRangeType.UnorderedAccessView, 1, 0), new DescriptorRange1(DescriptorRangeType.ShaderResourceView, 1, 0) }; RootParameter1 rootParameter = new RootParameter1(new RootDescriptorTable1(descriptorRanges), ShaderVisibility.All); var rootSignatureDescription = new VersionedRootSignatureDescription(new RootSignatureDescription1(RootSignatureFlags.None, new[] { rootParameter })); var rootSignature = device.CreateRootSignature(rootSignatureDescription); PipelineState pipelineState = new PipelineState(device, rootSignature, shaderBytecode); // Execute computer shader using (CommandList commandList = new CommandList(device, CommandListType.Compute)) { commandList.SetPipelineState(pipelineState); commandList.SetComputeRootDescriptorTable(0, descriptorSet); commandList.Dispatch(1, 1, 1); await commandList.FlushAsync(); } // Print matrix Console.WriteLine("Before:"); PrintMatrix(array, width, height); destinationBuffer.GetData(outputArray.AsSpan()); Console.WriteLine(); Console.WriteLine("After:"); PrintMatrix(outputArray, width, height); }
public void TestComputeShader(Vector3 postion, float[] heightmap) { Init_perm(0); int f_sizeX = 10; int f_sizeZ = 10; int perMeterX = 4; int perMeterZ = 4; int voxelOffset_x = 10; int voxelOffset_y = 10; Heightmap = heightmap; intermediate = new Plant[f_sizeX * perMeterX * f_sizeZ * perMeterZ]; int indexBuff_size = f_sizeX * perMeterX * f_sizeZ * perMeterZ * 8 * 3; Debug.Log("indexBuff_size: " + indexBuff_size); vertexData = new VertexData[indexBuff_size]; indices = GenIndices(f_sizeX * perMeterX, f_sizeZ * perMeterZ); ComputeBuffer buffer = new ComputeBuffer(heightmap.Length, sizeof(float)); buffer.SetData(heightmap); ComputeBuffer output_buff = new ComputeBuffer(intermediate.Length, Plant.GetSize()); output_buff.SetData(intermediate); //ComputeBuffer g_buff = new ComputeBuffer(indexBuff_size, sizeof(int)); GraphicsBuffer g_buff = new GraphicsBuffer(GraphicsBuffer.Target.Index, indices.Length, sizeof(int)); g_buff.SetData(indices); ComputeBuffer v_buff = new ComputeBuffer(indexBuff_size, VertexData.GetSize()); v_buff.SetData(vertexData); int k = shader.FindKernel("CSMain"); int c_k = shader.FindKernel("CompileMesh"); shader.SetInt("sizeX", SmoothVoxelSettings.ChunkSizeX); shader.SetInt("sizeZ", SmoothVoxelSettings.ChunkSizeZ); shader.SetInt("f_sizeX", f_sizeX); shader.SetInt("f_sizeZ", f_sizeZ); shader.SetInt("perMeterX", perMeterX); shader.SetInt("perMeterZ", perMeterZ); shader.SetInt("voxel_offset_x", voxelOffset_x); shader.SetInt("voxel_offset_z", voxelOffset_y); shader.SetBuffer(k, "heightmap", buffer); shader.SetBuffer(k, "intermediate", output_buff); shader.SetBuffer(c_k, "intermediate", output_buff); //shader.SetBuffer(c_k, "indices", g_buff); shader.SetBuffer(c_k, "vertex", v_buff); shader.Dispatch(k, f_sizeX * 4, 1, f_sizeZ * 4); shader.Dispatch(c_k, 1, 1, 1); v_buff.GetData(vertexData); g_buff.GetData(indices); verts = new List <Vector3>(); uv = new List <Vector2>(); normals = new List <Vector3>(); for (int i = 0; i < indexBuff_size; i++) { verts.Add(vertexData[i].Vertex); uv.Add(vertexData[i].UV); normals.Add(vertexData[i].Normal); } rend = GetComponent <MeshRenderer>(); rend.material.SetPass(0); rend.material.SetBuffer("_Vertex", v_buff); rend.material.SetTexture("_permutation", perm_tex); MeshFilter filter = gameObject.GetComponent <MeshFilter>(); Mesh mesh = new Mesh(); mesh.vertices = new Vector3[indexBuff_size];//verts.ToArray(); mesh.triangles = indices; //mesh.uv = uv.ToArray(); Vector3 corner = postion; //new Bounds() Bounds b = new Bounds(corner + new Vector3(SmoothVoxelSettings.MeterSizeX / 2 - 0.5f, SmoothVoxelSettings.MeterSizeY / 2 - 0.5f, SmoothVoxelSettings.MeterSizeZ / 2 - 0.5f), new Vector3(SmoothVoxelSettings.MeterSizeX + 1, SmoothVoxelSettings.MeterSizeY + 1, SmoothVoxelSettings.MeterSizeZ + 1)); mesh.bounds = b; filter.sharedMesh = mesh; inited = true; //Vector3 corner = postion + new Vector3(voxelOffset_x, 0, voxelOffset_y); //Bounds b = new Bounds(corner + new Vector3(f_sizeX / 2, SmoothVoxelSettings.ChunkSizeY / 2, f_sizeZ / 2), new Vector3(f_sizeX / 2, SmoothVoxelSettings.ChunkSizeY / 2, f_sizeZ / 2)); //Graphics.DrawProcedural(rend.material, b, MeshTopology.Triangles, indexBuff_size); // Graphics.DrawProceduralIndirect(rend.material, b, MeshTopology.Triangles, g_buff); //Graphics.DrawProcedural(rend.material, b, MeshTopology.Triangles, g_buff, indices.Length); return; output_buff.GetData(intermediate); List <int> tris = new List <int>(); for (int x = 0; x < f_sizeX * 4; x++) { for (int z = 0; z < f_sizeZ * 4; z++) { Plant res = intermediate[x * (f_sizeZ * 4) + z]; int offset = verts.Count; verts.AddRange(res.q1.GetVerts()); tris.AddRange(res.q1.GetTris(offset)); uv.AddRange(res.q1.GetUVs()); verts.AddRange(res.q2.GetVerts()); tris.AddRange(res.q2.GetTris(offset)); uv.AddRange(res.q2.GetUVs()); verts.AddRange(res.q3.GetVerts()); tris.AddRange(res.q3.GetTris(offset)); uv.AddRange(res.q3.GetUVs()); //Debug.DrawRay(verts[0], res.normal, Color.green, 1000000); //Debug.Log("|" + res.q1.ToString() + " " + res.q2.ToString() + " " + res.q3.ToString() + " | "); //Vector4 res = output[x * (20 * 4) + z]; //Vector3 normal = res; //float height = res.w; //Vector3 point = new Vector3(x / 4f, height, z / 4f); //Debug.DrawRay(point, normal, Color.green, 1000000); /*if (x % 8 == 0 && * z % 8 == 0) * { * Vector3 t1 = GetTangent(normal, Vector3.forward); * Vector3 t2 = GetTangent(normal, Vector3.right); * * Quaternion q1 = Quaternion.LookRotation(normal, Vector3.up); * //Quaternion q2 = Quaternion.LookRotation(t2, Vector3.up); * * * * Debug.DrawRay(point, normal, Color.green, 1000000); * //Debug.DrawRay(point, t1, Color.blue, 1000000); * //Debug.DrawRay(point, t2, Color.red, 1000000); * //Quaternion quat = q1 * q2; * //Instantiate(obj, point, q1); * }*/ } } Debug.Log("Num tris: " + tris.Count); mesh.vertices = verts.ToArray(); mesh.triangles = tris.ToArray(); mesh.uv = uv.ToArray(); mesh.RecalculateNormals(); filter.sharedMesh = mesh; }
public static bool Run(GrassBakeSettings settings, int lod, out Mesh generatedMesh) { GrassLODLevelSettings currentLOD; try { currentLOD = settings.grassLODLevelSettings[lod]; } catch (Exception e) { Console.WriteLine(e); generatedMesh = null; return(false); } DecomposeMesh(currentLOD.grassBladeMesh, 0, out SourceVertex[] sourceGrassBladeVertices, out int[] sourceGrassBladeIndices); int numBlades = (int)((settings.extents.x / settings.numTiles.x) * (settings.extents.y / settings.numTiles.y) / (currentLOD.density * currentLOD.density)); GeneratedVertex[] generatedVertices = new GeneratedVertex[numBlades * sourceGrassBladeVertices.Length]; int[] generatedIndices = new int[numBlades * sourceGrassBladeIndices.Length]; GraphicsBuffer sourceGrassBladeVertexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, sourceGrassBladeIndices.Length, SOURCE_VERTEX_STRIDE); GraphicsBuffer sourceGrassBladeIndexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, sourceGrassBladeIndices.Length, SOURCE_INDEX_STRIDE); GraphicsBuffer generatedVertexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, generatedVertices.Length, GENERATED_VERTEX_STRIDE); GraphicsBuffer generatedIndexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, generatedIndices.Length, GENERATED_INDEX_STRIDE); ComputeShader shader = settings.computeShader; int idGrassKernel = shader.FindKernel("CSMain"); shader.SetBuffer(idGrassKernel, "_SourceGrassBladeVertices", sourceGrassBladeVertexBuffer); shader.SetBuffer(idGrassKernel, "_SourceGrassBladeIndices", sourceGrassBladeIndexBuffer); shader.SetBuffer(idGrassKernel, "_GeneratedVertices", generatedVertexBuffer); shader.SetBuffer(idGrassKernel, "_GeneratedIndices", generatedIndexBuffer); shader.SetVector("_MinMaxRandomScale", currentLOD.minMaxScale); shader.SetVector("_TileSize", settings.extents / settings.numTiles); shader.SetFloat("_Density", currentLOD.density); shader.SetFloat("_MaxRandomPositionShift", currentLOD.maxRandomPositionShift); shader.SetInt("_NumGrassBladeVertices", sourceGrassBladeVertices.Length); shader.SetInt("_NumGrassBladeIndices", sourceGrassBladeIndices.Length); sourceGrassBladeVertexBuffer.SetData(sourceGrassBladeVertices); sourceGrassBladeIndexBuffer.SetData(sourceGrassBladeIndices); int numBladesRemaining = numBlades; for (int i = 0; i <= generatedVertices.Length / MAX_VERTS_PER_DISPATCH; ++i) { int maxBlades = MAX_VERTS_PER_DISPATCH / sourceGrassBladeVertices.Length; int numBladesToCalculate = numBladesRemaining > maxBlades ? maxBlades : numBladesRemaining; if (numBladesRemaining == 0) { break; } shader.SetInt("_NumBlades", numBladesToCalculate); shader.SetInt("_StartBladeIndex", i * maxBlades); shader.SetInt("_StartVertexIndex", i * Mathf.FloorToInt((float)MAX_VERTS_PER_DISPATCH / sourceGrassBladeVertices.Length) * sourceGrassBladeVertices.Length); shader.GetKernelThreadGroupSizes(idGrassKernel, out uint threadGroupSize, out _, out _); int dispatchSize = Mathf.CeilToInt((float)numBladesToCalculate / threadGroupSize); shader.Dispatch(idGrassKernel, dispatchSize, 1, 1); generatedVertexBuffer.GetData(generatedVertices, i * maxBlades * sourceGrassBladeVertices.Length, 0, numBladesToCalculate * sourceGrassBladeVertices.Length); generatedIndexBuffer.GetData(generatedIndices, i * maxBlades * sourceGrassBladeIndices.Length, 0, numBladesToCalculate * sourceGrassBladeIndices.Length); numBladesRemaining -= numBladesToCalculate; } generatedMesh = ComposeMesh(generatedVertices, generatedIndices); sourceGrassBladeVertexBuffer.Release(); sourceGrassBladeIndexBuffer.Release(); generatedVertexBuffer.Release(); generatedIndexBuffer.Release(); return(true); }