Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Drawing geometry from interleaved buffer.

Discussion in 'General Graphics' started by PetiteViking, Nov 7, 2023.

  1. PetiteViking

    PetiteViking

    Joined:
    Nov 7, 2023
    Posts:
    3
    Hi!
    I need to draw geometries using an indexed draw call with an interleaved buffer that I am given.

    To begin with, I would like to just draw a single triangle on the screen. From there, the rest should be simple.
    Currently, I am setting up my buffers and issuing the draw call like this:

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using Vector2 = System.Numerics.Vector2;
    4. using Vector3 = UnityEngine.Vector3;
    5.  
    6. public class Test : MonoBehaviour
    7. {
    8.     // Define the structure of your vertex data
    9.     private struct VertexData
    10.     {
    11.         public Vector3 position;
    12.         public Color32 color;
    13.         public Vector2 uv;
    14.     };
    15.  
    16.     private GraphicsBuffer vertexBuffer;
    17.     private GraphicsBuffer indexBuffer;
    18.     private Material material;
    19.  
    20.     void Start()
    21.     {
    22.         int vertexCount = 3;
    23.         vertexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, vertexCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(VertexData)));
    24.         VertexData[] vertices = new VertexData[vertexCount];
    25.         vertices[0] = new VertexData { position = new Vector3(0, 0, 0), color = new Color32(0, 0, 255, 255), uv = new Vector2(0, 0) };
    26.         vertices[1] = new VertexData { position = new Vector3(1, 0, 0), color = new Color32(0, 255, 0, 255), uv = new Vector2(1, 0) };
    27.         vertices[2] = new VertexData { position = new Vector3(0, 1, 0), color = new Color32(255, 0, 0, 255), uv = new Vector2(0, 1) };
    28.         vertexBuffer.SetData(vertices);
    29.  
    30.         int indexCount = 3;
    31.         indexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Index, indexCount, sizeof(int));
    32.         int[] indices = new int[indexCount];
    33.         indices[0] = 0;
    34.         indices[1] = 1;
    35.         indices[2] = 2;
    36.         indexBuffer.SetData(indices);
    37.  
    38.         material = new Material(Shader.Find("Test/TestShader"));
    39.     }
    40.  
    41.     private void OnDestroy()
    42.     {
    43.         indexBuffer?.Dispose();
    44.         vertexBuffer?.Dispose();
    45.     }
    46.  
    47.     void Update()
    48.     {
    49.         RenderParams rp = new RenderParams(material);
    50.         rp.matProps = new MaterialPropertyBlock();
    51.         rp.matProps.SetBuffer("vertexBuffer", vertexBuffer);
    52.         Graphics.RenderPrimitivesIndexed(rp, MeshTopology.Triangles, indexBuffer, 3, 0, 1);
    53.     }
    54. }
    55.  
    and have written the corresponding shader:

    Code (CSharp):
    1.  
    2. Shader"Test/TestShader"
    3. {
    4. SubShader
    5. {
    6. Pass
    7. {
    8. CGPROGRAM
    9. #pragma vertex vert
    10. #pragma fragment frag
    11.  
    12. #include "UnityCG.cginc"
    13.  
    14. struct VertexData
    15. {
    16.     float3 pos   : POSITION;
    17.     float4 color : COLOR;
    18.     float2 uv    : TEXCOORD0;
    19. };
    20.  
    21. struct v2f
    22. {
    23.     float4 pos   : SV_POSITION;
    24.     float4 color : COLOR0;
    25.     float2 uv    : TEXCOORD0;
    26. };
    27.  
    28. StructuredBuffer<VertexData> vertexBuffer;
    29.  
    30. v2f vert(uint vertexID : SV_VertexID)
    31. {
    32.     v2f o;
    33.     VertexData vertexData = vertexBuffer[vertexID];
    34.     o.pos = float4(vertexData.pos, 1);
    35.     o.color = vertexData.color;
    36.     o.uv = vertexData.uv;
    37.     return o;
    38. }
    39.  
    40. float4 frag(v2f i) : SV_Target
    41. {  
    42.     return i.color;
    43. }
    44. ENDCG
    45. }
    46. }
    47. }
    48.  
    The shader seems to compile fine but I am not seeing the triangle rendered on the screen. I suppose I am forgetting something. From what I have read, if I do not set a render target explicitly, the screen is used as default render target.

    Does anyone know where I am going wrong?
     
    Last edited: Nov 7, 2023
  2. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,841
    I'd try checking your winding order. Unity uses clockwise winding for front-facing polygons, at first sight your triangle seems to be using CCW.

    Also your vertex shader is not transforming vertex coordinates at all (don't know if this is intentional, just pointing that out). Typically you want your mesh vertices expressed in object space, then converted to clip space in the vertex shader.
     
    Last edited: Nov 8, 2023
  3. PetiteViking

    PetiteViking

    Joined:
    Nov 7, 2023
    Posts:
    3
    Thanks for the answer!
    You are right, I am not doing any transformations. That is because I want to draw in screen space. I couldn't find a good way to draw a fullscreen quad in Unity so I figured I'd simply draw into the camera's render target directly.

    Unfortunately, that doesn't seem to work. I got to a point where I can draw the triangle in the scene, using the `UNITY_MATRIX_VP` builtin matrix. Without transformations though, nothing is rendered.
     
  4. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,841
    FYI drawing a fullscreen quad in Unity is typically done using Blit(). This allows you to render a fullscreen quad using a custom material/texture onto a RenderTexture, or the screen:


    Vertex range in clip space varies depending on the graphics API used. Unity abstracts this away for you when you use UNITY_MATRIX_P (or _VP, or _MVP) or UnityObjectToClipPos(pos), however if you're not going to transform the vertex then you must account for this yourself.

    What's probably happening is that your triangle is outside of or at the very limits of clip space and getting culled by the GPU.

    See: https://docs.unity3d.com/2019.1/Documentation/Manual/SL-PlatformDifferences.html
     
    Last edited: Nov 10, 2023
  5. ekakiya

    ekakiya

    Joined:
    Jul 25, 2011
    Posts:
    79