Search Unity

Feature Request Support DrawProcedural, ComputeBuffer and SV_VertexID

Discussion in 'Shader Graph' started by cecarlsen, Aug 24, 2020.

  1. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    864
    How far are we from being able to call DrawProcedural from the Graphics or CommandBuffer class and read data from a ComputeBuffer in ShaderGraph using SV_VertexID for lookup?

    I have been waiting for this feature for ages. ShaderGraph is close to useless for me until this feature is supported.

    Alternatively, how about allowing us to fill a Mesh with data from a ComputeBuffer, or GraphicsBuffer (if work is being done on that front).

    All the best
    Carl Emil
     
  2. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    Just having access to SV_VertexID (which surely can't be a complex feature to add) would open up a bunch of alternative use cases.
     
  3. Lecks

    Lecks

    Joined:
    May 13, 2013
    Posts:
    18
    I think we would also need access to arrays (possibly arrays of custom structs unless we use a buffer for each vertex element) to be able to do much with SV_VertexID. Personally I think DrawProceduralIndirect with 2 extra params (vertex description and vertex buffer) would be the simplest way to get procedural stuff into Shadergraph. Shadergraph wouldn't need to be updated at all, and it would make things easier for the standard render pipeline too (normal/surface shaders would work).
     
  4. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    I disagree. You can easily fake buffers and arrays with textures (that's how most of the clever visual effects graph stuff is doing it)

    But not having a vertex index cripples even this workaround.

    My point is that vertex indices is potentially a quick afternoon's work whilst buffers and arrays might be more complex. So please give us the critical part of the jigsaw without needing to wait a year for it to filter through your kanban board.
     
    Egad_McDad and cultureulterior like this.
  5. andybak

    andybak

    Joined:
    Jan 14, 2017
    Posts:
    569
    Just hit another situation where I had to dump using Shader Graph because of the lack of vertex IDs.

    Any chance this is being considered?
     
  6. Onat-H

    Onat-H

    Joined:
    Mar 11, 2015
    Posts:
    195
    Add me to the list of people who think this really is an essential feature :)
     
    andybak likes this.
  7. Lecks

    Lecks

    Joined:
    May 13, 2013
    Posts:
    18
    I made a Vertex ID node.. but it has to go in the shadergraph/editor package (I'm on 10.2.0), and it returns a float instead of an int so it's not ideal but it lets me use shadergraphs with computed vertices.
    Code (CSharp):
    1. using UnityEditor.Graphing;
    2.  
    3. namespace UnityEditor.ShaderGraph
    4. {
    5.     [Title("Vertex ID", "Vertex ID")]
    6.     class VertexIDNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireVertexID
    7.     {
    8.         public const int kVertexIdOutputSlotId = 0;
    9.  
    10.         public const string kOutputSlotVertexIdName = "Vertex ID";
    11.  
    12.         public VertexIDNode()
    13.         {
    14.             name = "Vertex ID";
    15.             UpdateNodeAfterDeserialization();
    16.         }
    17.  
    18.         public sealed override void UpdateNodeAfterDeserialization()
    19.         {
    20.             AddSlot(new Vector1MaterialSlot(kVertexIdOutputSlotId, kOutputSlotVertexIdName, kOutputSlotVertexIdName, SlotType.Output, 0, ShaderStageCapability.Vertex));
    21.  
    22.             RemoveSlotsNameNotMatching(new[] { kVertexIdOutputSlotId });
    23.         }
    24.  
    25.         public bool RequiresVertexID(ShaderStageCapability stageCapability = ShaderStageCapability.All)
    26.         {
    27.             return true;
    28.         }
    29.  
    30.         public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
    31.         {
    32.             sb.AppendLine("uint {0} = IN.VertexID;", GetVariableNameForSlot(kVertexIdOutputSlotId));
    33.         }
    34.     }
    35. }
    Using that node I can do this:
    upload_2020-12-5_15-43-45.png

    with this code in ReadVertexData.hlsl:
    Code (CSharp):
    1. struct InputVertex
    2. {
    3.     float3 position;
    4.     float3 normal;
    5.     float3 tangent;
    6. };
    7. StructuredBuffer<InputVertex> _Vertices;
    8. void GetPositionNormalTangent_float(uint index,out float3 position, out float3 normal, out float3 tangent)
    9. {
    10.     position = _Vertices[index].position;
    11.     normal = _Vertices[index].normal;
    12.     tangent = _Vertices[index].tangent;
    13. }
    Any chance we could get this simple node included in Shadergraph until a more appropriate version (using ints) is ready?
     
    Dinamytes and lilacsky824 like this.
  8. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    864
    Thanks for sharing @Lecks

    I'll also point at a recent ComputeShader tutorial by CatLikeCoding (@Jasper-Flick) that has a similar solution.
    https://catlikecoding.com/unity/tutorials/basics/compute-shaders/

    I too hope that this custom function will be converted to a standard node soon.

    But what I hope for even more, is the ability to fill meshes directly on the GPU. For example by extending the functionality of GraphicsBuffer.
     
    GameDeveloper1111 likes this.
  9. Lecks

    Lecks

    Joined:
    May 13, 2013
    Posts:
    18
    @cecarlsen Yeah agreed, or at least be able to set a vertex buffer with DrawProceduralIndirect so the mesh isn't necessary.

    But it seems like a Vertex ID node would be the simplest way to get us from drawing computed vertex using Shadergraph being impossible, to being possible. I was hoping someone from Unity would see those 35 lines and just chuck them in Shadergraph 10.2.2, but it's probably unlikely :).
     
  10. Onat-H

    Onat-H

    Joined:
    Mar 11, 2015
    Posts:
    195
    LooperVFX and Dinamytes like this.
  11. cdelabrouhe

    cdelabrouhe

    Joined:
    Nov 26, 2020
    Posts:
    2
    Hi @Lecks
    Your script seems very interesting, however in Unity 2020 the class AbstractMaterialNode isn't accessible anymore. They have implemented a Custom Function node directly in the shader graph, but I can't find a way to get the VertexID.

    The tutorial sent by @cecarlsen seems interesting too, however I can't make the procedural stuff work either. To summer: I'm stuck with this VertexID node that I can't reproduce using Custom Function node.

    Do you have an idea on how to do that ? Because what I see from you code seems to fit at 100% with my needs.

    Thanks by advance for your help !
    Chris
     
  12. cdelabrouhe

    cdelabrouhe

    Joined:
    Nov 26, 2020
    Posts:
    2
    Well, I ended up by storing the VertexID into the vertex color => it's a bit hacky but it works.
     
  13. Lecks

    Lecks

    Joined:
    May 13, 2013
    Posts:
    18
    My example was based on editing the shadergraph package (copying the whole thing to your packages folder, and adding the class I pasted above). If AbstractMaterialNode was accessible, we could just put it in our project, but unfortunately that's not the case. My one still seems to work with Shadergraph 12.0.0 / 2021.2.0a8
     
  14. LooperVFX

    LooperVFX

    Joined:
    Dec 3, 2018
    Posts:
    180
    These features have landed in alpha releases 2021.2.0a9+ and they seem to work in my cursory tests.

    https://unity3d.com/unity/alpha/2021.2.0a9

     
    PraetorBlue and cecarlsen like this.
  15. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Awesome news!

    Anyone have any idea about where in the pipeline ComputeBuffer/StructuredBuffer support is for ShaderGraph? Is it even in the pipeline?
     
    Last edited: Mar 25, 2021
  16. LooperVFX

    LooperVFX

    Joined:
    Dec 3, 2018
    Posts:
    180
    PraetorBlue likes this.