Search Unity

  1. Dismiss Notice
  2. All Pro and Enterprise subscribers: find helpful & inspiring creative, tech, and business know-how in the new Unity Success Hub. Sign in to stay up to date.
    Dismiss Notice

Resolved How to draw triangles using StructuredBuffers and Graphics.DrawProceduralNow?

Discussion in 'Universal Render Pipeline' started by TheGabelle, Feb 25, 2021.

  1. TheGabelle

    TheGabelle

    Joined:
    Aug 23, 2013
    Posts:
    229
    I am very new to writing shaders and attempting to draw an arbitrary set of triangles from rapidly updated procedural data. I want to use the shader like this:

    Code (CSharp):
    1. void Render()
    2. {
    3.       // set whatever buffer data is needed
    4.       _triangleMaterial.SetPass(0);
    5.       Graphics.DrawProceduralNow(MeshTopology.Triangles, _triangleCount * 3);
    6. }
    I'm struggling to create the shader. Instead of modifying a mesh, I'd like to write the data to structured buffers. For each triangle I want to pass three vertex positions, three vertex normals, three vertex colors, and three vertex uvs.
    Code (CSharp):
    1. StructuredBuffer<float3> positionsBuffer;
    2. StructuredBuffer<float3> normalsBuffer;
    3. StructuredBuffer<float2> uvsBuffer;
    4. StructuredBuffer<float4> colorsBuffer;
    What do I need to do within the shader to make it work?
     
  2. TheGabelle

    TheGabelle

    Joined:
    Aug 23, 2013
    Posts:
    229
    I got it to work. I forgot I needed to add the script specifically to the Camera GO instead of an empty GO.
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.Rendering;
    6. public class TrianglesTest : MonoBehaviour
    7. {
    8.  
    9.     // Vertices Buffer
    10.     ComputeBuffer _verticesBuffer;
    11.  
    12.     static readonly int verticesBuffer = Shader.PropertyToID("verticesBuffer");
    13.  
    14.     public Vector4[] vertices;
    15.     public Material triangleMaterial;
    16.  
    17.     void Awake()
    18.     {
    19.         RenderPipelineManager.endFrameRendering += (arg1, arg2) => Render();
    20.     }
    21.  
    22.     void OnPostRender()
    23.     {
    24.         Render();
    25.     }
    26.  
    27.  
    28.     void OnDrawGizmos()
    29.     {
    30.         Render();
    31.     }
    32.  
    33.  
    34.     void CopyFromCpuToGpu()
    35.     {
    36.         if (_verticesBuffer == null || _verticesBuffer.count != vertices.Length)
    37.         {
    38.             if (_verticesBuffer != null)
    39.             {
    40.                 _verticesBuffer.Release();
    41.                 _verticesBuffer = null;
    42.             }
    43.  
    44.             _verticesBuffer = new ComputeBuffer(vertices.Length, 4*4);
    45.             triangleMaterial.SetBuffer(verticesBuffer, _verticesBuffer);
    46.         }
    47.  
    48.         _verticesBuffer.SetData(vertices, 0, 0, vertices.Length);
    49.     }
    50.  
    51.     internal void Render()
    52.     {
    53.         CopyFromCpuToGpu();
    54.         triangleMaterial.SetPass(0);
    55.         Graphics.DrawProceduralNow(MeshTopology.Triangles, vertices.Length);
    56.     }
    57. }
    Code (CSharp):
    1. Shader "BurstDrawTrianglesShader" {
    2.     Properties
    3.     {
    4.     }
    5.     SubShader
    6.     {
    7.         Tags {"RenderType" = "Opaque" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" "ShaderModel"="2.0"}
    8.         Cull Off
    9.  
    10.         Pass
    11.         {
    12.             Name "Unlit"
    13.  
    14.             HLSLPROGRAM
    15.             #pragma exclude_renderers gles gles3 glcore
    16.             #pragma target 4.5
    17.  
    18.             #pragma vertex vert
    19.             #pragma fragment frag
    20.  
    21.  
    22.             #include "UnityCG.cginc"
    23.  
    24.             uniform StructuredBuffer<float4> verticesBuffer;
    25.  
    26.             struct vtf
    27.             {
    28.                 float4 vertex : SV_POSITION;
    29.                    float4 color : TEXCOORD0;
    30.             };
    31.  
    32.             // color packed into float4.w (1 byte per RGBA channel)
    33.             float4 unpack(float i)
    34.             {
    35.                 return float4(i / 262144.0, i / 4096.0, i / 64.0, i) % 64.0 / 63;
    36.             }
    37.  
    38.             vtf vert(uint vid : SV_VertexID)
    39.             {
    40.                 vtf output;
    41.                 float4 pos = verticesBuffer[vid];
    42.                 output.vertex = mul(UNITY_MATRIX_VP, float4(pos.xyz, 1));
    43.                 output.color = unpack(pos.w);
    44.                 return output;
    45.             }
    46.  
    47.             half4 frag(vtf input) : SV_Target
    48.             {
    49.                 return input.color;
    50.             }
    51.             ENDHLSL
    52.         }
    53.     }
    54.     SubShader
    55.     {
    56.         Pass
    57.         {
    58.             CGPROGRAM
    59.  
    60.             #pragma vertex vert
    61.             #pragma fragment frag
    62.             #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight
    63.             #pragma target 4.5
    64.  
    65.             #include "UnityCG.cginc"
    66.  
    67.             StructuredBuffer<float4> verticesBuffer;
    68.  
    69.             struct v2f
    70.             {
    71.                 float4 pos : SV_POSITION;
    72.                 float4 color : TEXCOORD0;
    73.             };
    74.  
    75.             float4 unpack(float i)
    76.             {
    77.                 return float4(i / 262144.0, i / 4096.0, i / 64.0, i) % 64.0 / 63;
    78.             }
    79.  
    80.             v2f vert(uint vid : SV_VertexID)
    81.             {
    82.                 v2f o;
    83.                 float4 pos = verticesBuffer[vid];
    84.                 o.pos = mul(UNITY_MATRIX_VP, float4(pos.xyz, 1));
    85.                 o.color = unpack(pos.w);
    86.                 return o;
    87.             }
    88.  
    89.             fixed4 frag(v2f i) : SV_Target
    90.             {
    91.                 return i.color;
    92.             }
    93.  
    94.             ENDCG
    95.         }
    96.     }
    97. }
     
unityunity