How to correctly set up Shader Graph for MaterialPropertyBlock.

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)

5073020--498803--upload_2019-10-16_13-52-33.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?

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.

2 Likes

@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.

For anyone interested in near future, here is another proposed solution so far.

It will require at least 2020.1a however.

Unless someone knows how to make it work with earlier Unity versions.

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

public class ShaderSettings : MonoBehaviour
{
    private SpriteRenderer rend;
    private MaterialPropertyBlock block;

    public float fps = 1f;
    public int cols = 1;
    public int rows = 1;
    public Vector2 custom_offset = Vector2.zero;
    public Color recolor = Color.white;

    void Awake()
    {
        rend = gameObject.GetComponent<SpriteRenderer>();
        block = new MaterialPropertyBlock();
        SetBlock();
    }

    private void SetBlock()
    {
      
        rend.GetPropertyBlock(block);
        block.SetFloat("_FPS", fps);
        block.SetInt("_Cols", cols);
        block.SetInt("_Rows", rows);
        block.SetVector("_CustomOffset", custom_offset);
        block.SetColor("_Recolor", recolor);
        rend.SetPropertyBlock(block);
    }

    }