Search Unity

Question How to correctly set up Shader Graph for MaterialPropertyBlock.

Discussion in 'Shader Graph' started by Antypodish, Oct 16, 2019.

  1. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    I read few threads, where Shader Graph and MaterialPropertyBlock kewords appeared.
    But I could find no solid answer.

    So my question is, how to correctly setup shader graph to work with MaterialPropertyBlock.
    For instance I have circular shader, which I made using LRP Shader Graph and render many instances.
    Problem is, my passed property array is always taking values from index 0. (see blue line)

    upload_2019-10-16_15-29-40.png

    I use Graphics.DrawMeshInstanced approach, to render multiple instances, with same material and mesh.
    I use propertyBlock.SetFloatArray, to set all properties I need, for all rendered instances.
    All instances are rendered at correct positions / orientation.
    But shader block properties are taken only from index 0, while which instance has own property set in the corresponding index array.

    So I believe, there is something missing in shader graph, which otherwise, can be coded manually.
    I suppose can edit compiled shader graph from temp folder.

    But maybe there is something simpler, which can switch MaterialPropertyBlock compatibility?

    Unless I miss something else?
     
  2. julian-moschuering

    julian-moschuering

    Joined:
    Apr 15, 2014
    Posts:
    529
    Current Shader Graph does not support per instance properties. This should be coming with 7.2 although I'm not sure that it will work with DrawInstanced and MaterialPropertyBlock in the beginning as I didn't try it.

    7.2 from github (https://github.com/Unity-Technologies/ScriptableRenderPipeline) has per instance properties. I'm using the version from release/2019.3 branch.
     
    mkracik and Antypodish like this.
  3. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    @julian-moschuering I will look into more detail for that github version.
    But probably I will decide write shader by hand, even is not my most favor route.
     
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
  5. ExtraCat

    ExtraCat

    Joined:
    Aug 30, 2019
    Posts:
    52
    Recently I've encountered the need to use instanced properties for materials that use a shader created in shader graph.And all threads I found claimed it cannot be done.

    Turns out while it's not 100% convenient, nothing prevents us from writing a simple script that sets the required material property block, and attaching it to the object in question. Ie something like


    Code (CSharp):
    1. public class ShaderSettings : MonoBehaviour
    2. {
    3.     private SpriteRenderer rend;
    4.     private MaterialPropertyBlock block;
    5.  
    6.     public float fps = 1f;
    7.     public int cols = 1;
    8.     public int rows = 1;
    9.     public Vector2 custom_offset = Vector2.zero;
    10.     public Color recolor = Color.white;
    11.  
    12.     void Awake()
    13.     {
    14.         rend = gameObject.GetComponent<SpriteRenderer>();
    15.         block = new MaterialPropertyBlock();
    16.         SetBlock();
    17.     }
    18.  
    19.     private void SetBlock()
    20.     {
    21.      
    22.         rend.GetPropertyBlock(block);
    23.         block.SetFloat("_FPS", fps);
    24.         block.SetInt("_Cols", cols);
    25.         block.SetInt("_Rows", rows);
    26.         block.SetVector("_CustomOffset", custom_offset);
    27.         block.SetColor("_Recolor", recolor);
    28.         rend.SetPropertyBlock(block);
    29.     }
    30.  
    31.     }
     
    Last edited: Mar 22, 2021