예제 #1
0
 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
 }
예제 #2
0
        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));
        }
예제 #3
0
        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!");
        }
예제 #4
0
    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);
    }
예제 #6
0
        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);
        }
예제 #7
0
    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;
    }
예제 #8
0
        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);
        }