Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Vector array support in Shader Graph

Discussion in 'Graphics Experimental Previews' started by bac9-flcl, Oct 26, 2018.

  1. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    As far as I see, Shader Graph has a texture array sampling node, but has no vector array node. I might be missing correct search terms, though.

    If it's actually missing - can we expect to get it anytime soon, and if not, can someone tell me if it's possible to manually implement a vector array node? :)
     
  2. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Unity's material system doesn't have support for serializing arrays of data. You can set an array on a material, but it doesn't have a way to add properties for them.

    What I do a lot is store them in small lookup textures, though that won't help you much without writing a custom shader editor..
     
  3. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Yeah, I don't actually have any need for shader editors - I use vector arrays to pack values like smoothness and metalness in my tileset shader, allowing me to support rendering of each block in one draw call despite source assets using multi-materials. Kind of similar to MicroSplat. :) Those arrays are simply set from tileset data on game initialization, so I never edit them by hand and never need any in-material serialization.

    Are you saying that lack of serialization support is the only reason why Shader Graph doesn't support vector arrays?
     
  4. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Not necessarily, But I’d wager that having array support without being able to save the data or expose it like other properties would feel pretty broken.
     
  5. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Any update on this? It's impossible to reimplement any of our level or character shaders in Shader Graph without vector array support, and those enable us to save literal thousands of draw calls, so we are effectively blocked from trying HDRP.
     
    forteller likes this.
  6. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Encode your property values into a small lookup texture; I do this in most of my assets and for large numbers of properties it can actually be faster. If it’s texture array support you need you could wrap array access in a custom code node.
     
  7. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    That's a great idea for fixed properties, thanks! Can you recommend a good way to update such a lookup texture over time, though? One of the things I use arrays for per-bone damage in units, which is often updated over a dozen of units every frame - I suppose a per-unit R/W enabled texture of some sort could be feasibly used for that?
     
  8. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Yup; I do this in MicroSplat, though use a more elegant approach in one batch that doesn’t require a component. Basically I use a scriptable importer to make the scriptable object act as a texture to unity.
     
  9. juliano09

    juliano09

    Joined:
    Jun 14, 2018
    Posts:
    4
    Hey sir, could you explain this technique in a simple way for a shader starter guy?
     
  10. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    You can download MicroSplat in the Unity asset store (it’s free) and look at how the PropData class is used. The biggest issue is that Unity doesn’t serialize linear HDR textures correctly, and they recently decided they are not going to fix that bug, so you have two choices: one, construct the texture at runtime, or two, write a ScriptableAssetImporter to serialize and construct that data at import time (this is what I do in OneBatch)
     
    juliano09 likes this.
  11. juliano09

    juliano09

    Joined:
    Jun 14, 2018
    Posts:
    4
    I'm Trying to store a bunch of Gameobjects position and determine via shader the distance between those gameobjects without the need of making a vector3 property for each one, can't seem to find a way of doing this via shader graph. Any tip that could guide me into this? Thank you for the previous answer btw.
     
    StrangeWays777, ToxicTree and Nexer8 like this.
  12. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Nope, you need to write code to convert the data into a texture; once there the shader needs to look that up via a texture and UV set, which the graph should be able to do fine though.
     
    andrejpetelin likes this.
  13. songtianming

    songtianming

    Joined:
    Aug 3, 2018
    Posts:
    5
    Right now you can use "custom function node" to include a shader file; you can define vector array there and use mat.SetVectorArray to upload data.
     
  14. tomekkie2

    tomekkie2

    Joined:
    Jul 6, 2012
    Posts:
    973
    Does it work?
    As far as I know you have to place all the used shader properties on the shader graph blackboard.
    And you check these supposed to work locally on the material level as exposed, and leave unchecked these supposed to work globally.
    Will the VectorArray work if you can't put it there?
     
  15. Darkgaze

    Darkgaze

    Joined:
    Apr 3, 2017
    Posts:
    397
    IgorAherne and StrangeWays777 like this.
  16. RazHollander13

    RazHollander13

    Joined:
    Oct 16, 2018
    Posts:
    4
    I created a vector array node with @Darkgaze hack!
    Steps:
    1) Create a Custom Function in ShaderGraph as follows


    2) Create a file named CustomShader.cginc and paste this code inside
    3) drage the file into the shader node to the Source box
    Code (CSharp):
    1.  
    2. #ifndef CUSTOM_INSTANCING
    3. #define CUSTOM_INSTANCING
    4. // This allows multiple Custom Function nodes to use the same file
    5. // without trying to include the code multiple times (causing redefinition errors)
    6.  
    7. // Instancing Buffer
    8. UNITY_INSTANCING_BUFFER_START(Props)
    9.   UNITY_DEFINE_INSTANCED_PROP(float4 myFloatArray[2], [2]) // creates array of size 2
    10. UNITY_INSTANCING_BUFFER_END(Props)
    11.  
    12. // Custom Function "GetFirstElement", Outputs : float4
    13. void GetFirstElement_float(out float4 FirstElement){
    14.     float4 array[] = UNITY_ACCESS_INSTANCED_PROP(Props, myFloatArray);
    15.     FirstElement = array[0];
    16. }
    17.  
    18. #endif
    19.  
     
    Last edited: Jan 23, 2024
    ANU_CHEEKI_BREEKI likes this.