Search Unity

Graphics.DrawProcedural(MeshTopology.Quads, ...) working as Triangles

Discussion in 'Shaders' started by Tikkub, Aug 29, 2017.

  1. Tikkub

    Tikkub

    Joined:
    Jun 3, 2015
    Posts:
    4
    Hi,

    I'm trying to draw a mesh on the GPU based on quads.
    I'm using Graphics.DrawProcedural and specifying a Quad Topology.
    The problem is the result is exactly the same for Triangles and Quads.
    I tried to change the order of the vertices but no matter what, the shader only draw one triangle and not a quad.

    Here is my script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3. using System.Runtime.InteropServices;
    4.  
    5. public class Test : MonoBehaviour
    6. {
    7.     public Material material;
    8.     private ComputeBuffer buffer;
    9.     private Vector2[] vertices;
    10.  
    11.     private void Start()
    12.     {
    13.         vertices = new Vector2[]
    14.         {
    15.             new Vector2(0,0),
    16.             new Vector2(0,1),
    17.             new Vector2(1,1),
    18.             new Vector2(1,0),
    19.         };
    20.  
    21.         buffer = new ComputeBuffer(vertices.Length, Marshal.SizeOf(vertices.GetType().GetElementType()));
    22.         buffer.SetData(vertices);
    23.         material.SetBuffer("_vertices", buffer);
    24.     }
    25.  
    26.     private void OnPostRender()
    27.     {
    28.         material.SetPass(0);
    29.         Graphics.DrawProcedural(MeshTopology.Quads, vertices.Length);
    30.     }
    31.  
    32.     private void OnDestroy()
    33.     {
    34.         buffer.Dispose();
    35.     }
    36. }
    37.  
    And the shader

    Code (Boo):
    1. Shader "Test/ProceduralQuads"
    2. {
    3.     Properties
    4.     {
    5.         _Color("Color", Color) = (1,0,0,1)
    6.     }
    7.  
    8.     SubShader
    9.     {
    10.         Tags{ "RenderType" = "Opaque" "Queue" = "Overlay+10"}
    11.         LOD 100
    12.  
    13.         Pass
    14.         {
    15.             CGPROGRAM
    16.             #include "UnityCG.cginc"
    17.             #pragma target 3.5
    18.             #pragma vertex vert
    19.             #pragma fragment frag
    20.  
    21.             uniform float4 _Color;
    22.             uniform StructuredBuffer<float2> _vertices;
    23.  
    24.             struct appdata
    25.             {
    26.                 float4 vertex : POSITION;
    27.             };
    28.  
    29.             struct v2f
    30.             {
    31.                 float4 vertex : SV_POSITION;
    32.             };
    33.  
    34.             v2f vert(appdata v, uint vid : SV_VertexID)
    35.             {
    36.                 v2f o;
    37.                 o.vertex = float4(_vertices[vid],0,1);
    38.                 return o;
    39.             }
    40.  
    41.             fixed4 frag(v2f i) : SV_Target
    42.             {
    43.                 return _Color;
    44.             }
    45.             ENDCG
    46.         }
    47.     }
    48. }
    49.  
    I only see one triangle on screen. No quad.
    Is it a bug or am i doing something wrong ?
     
    Agent0023 likes this.
  2. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    Code (CSharp):
    1.         vertices = new Vector2[]
    2.         {
    3.             new Vector2(0,0),
    4.             new Vector2(0,1),
    5.             new Vector2(1,1),
    6.             new Vector2(1,1),
    7.             new Vector2(1,0),
    8.             new Vector2(0,0)
    9.         };
    It seems you have to use six vertices to build one quad from two triangles, even with MeshTopology.Quads :)

    You can also check another example with ComputeBuffer:
    https://github.com/przemyslawzaworski/Unity3D-CG-programming/blob/master/ProceduralGeometry.cs
    https://github.com/przemyslawzaworski/Unity3D-CG-programming/blob/master/ProceduralGeometry.shader
     
    Agent0023 likes this.
  3. Tikkub

    Tikkub

    Joined:
    Jun 3, 2015
    Posts:
    4
    Yes it's what i did for the moment.
    However why having a Quad topology if you have to send the same amount of data as Triangles.
    The main thing for me was to have less data to send to the GPU. It's non negligible (50% more data to send).
    So i don't understand what is the point to have a Quad topology ?
     
    Last edited: Aug 29, 2017
    Airmouse likes this.
  4. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    328
    For DirectX 11 quad tessellation.
    You can use standard quad based mesh imported from external modelling software or choose procedural solution with MeshTopology.Quads.
     
  5. Tikkub

    Tikkub

    Joined:
    Jun 3, 2015
    Posts:
    4
    It's why i wrote this post. The Quad topology is not working with Graphics.DrawProcedural. Or more precisely it's working if you send 6 vertices (Exactly like the Triangle topology) but it should work we 4 vertices.
     
    Airmouse likes this.
  6. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    265
    Old thread, I know, but I was trying to create a quad based tessellation myself and succeeded. @Tikkub probably just forgot to change the configuration of the hull and domain programs to use quads instead of triangles. Anyway, I've uploaded a small example to my Scratchpad repository on GitHub, if somebody is interested. It was build in Unity 2020.2.6f1 for the built-in rendering pipeline but will probably be easy to adjust for URP as well.
     
  7. wechat_os_Qy06eaOhICF9NcZoMWMLtv5cI

    wechat_os_Qy06eaOhICF9NcZoMWMLtv5cI

    Joined:
    Feb 1, 2018
    Posts:
    33
    I want to say,default quad mesh in Unity doesn't work for quad tesselation.and Your mesh doen't work with Drawmeshinstanceindirect....bad unity