Search Unity

MaterialPropertyBlock with Shader Graph?

Discussion in 'General Graphics' started by STUDIOCRAFTapps, Jun 20, 2019.

  1. STUDIOCRAFTapps

    STUDIOCRAFTapps

    Joined:
    Feb 4, 2015
    Posts:
    102
    I don't think I need to give much info for you to understand what I'm trying to achieve so I'm going to keep it simple.

    My goal is to instantiate a large amount of the same mesh but with different texture applied to them and render it as fast as possible. I found out about GPU instancing and decided to try it. To make instancing work, you probably already know that It needs two things, objects using the same mesh and same material.

    To be able to display multiple textures with the same material I created a shader (in shader graph) that takes in some sort of texture array (not unity's texture array, just one texture2D with a bunch of images of the same size next to each other) and a texture index propriety (with the exposed parameter set to false).

    After that, I toggle the GPU instancing checkbox on the material that uses the shader
    https://imgur.com/l3Pqxb1
    https://imgur.com/4k076Tq


    The material is already rendering the mesh it faster but now I need to change the material property that changes the texture used.

    To do that, instead of changing the parameter of a new instance of the same material, I found out that I needed to use a material property block. This is where I'm getting an issue. For some reasons, I can change the material property that changes the texture but for each time I set a new material to use in the property block, the amount of set pass calls increases dramatically to the point of reaching 5000 calls when using 15 different material. This is hard to explain, I'll demonstrate in code:

    This is the code I use to create a new object. Notice the material variable in the set float function of the property block? If it stays at the same value for each object, the set pass calls count is normal. However, if this value is different for multiple objects, the set pass call count increase. The more value this variable can be, the more calls I get. If instead of using material property block, I use a different instance of the same material, I get similar results: a hight set pass call count.

    I just don't get why the material property block seems to create different instance of my material instead of just changing the texture index parameter.

    Code (CSharp):
    1. GameObject buildAssetObject = Object.Instantiate(buildLoadManager.buildAssetPrefab, buildRoot.transform);
    2.         Renderer renderer = buildAssetObject.GetComponent<Renderer>();
    3.  
    4.         renderer.sharedMaterial = buildLoadManager.buildMat_0;
    5.         buildAssetObject.GetComponent<MeshFilter>().sharedMesh = buildLoadManager.meshes[meshIndex];
    6.         buildAssetObject.GetComponent<MeshCollider>().sharedMesh = buildLoadManager.meshes[meshIndex];
    7.  
    8.         renderer.GetPropertyBlock(materialPropertyBlock);
    9.         materialPropertyBlock.SetFloat(buildLoadManager.materialIDProperty, material);
    10.         renderer.SetPropertyBlock(materialPropertyBlock, 0);
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    8,126
    For you to be able to change a material's property and have instancing continue to work, that property has to be setup to be an instanced property. Unfortunately Shader Graph doesn't (yet) support instanced properties, so there's no way to do this with Shader Graph.

    However if you enable the SRP Batcher you might get similar performance improvements as instancing even with the increased draw calls.
     
  3. STUDIOCRAFTapps

    STUDIOCRAFTapps

    Joined:
    Feb 4, 2015
    Posts:
    102
    This option has already been toggled from the beginning.

    Do you know if there's any simple tutorial that could help me set up an instanced material with instanced propriety for LWRP. Once that's setup I could try porting my shader from graph to code
     
    Last edited: Jun 20, 2019
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    8,126
    You can take a shader graph, and right click on the master node to get the generated vertex fragment shader, this will be the easiest way to get a working shader to start with. After that it should just be a matter of following the directions for adding an instanced property in the official documentation.
    https://docs.unity3d.com/Manual/GPUInstancing.html
     
    Arathorn_J likes this.
  5. STUDIOCRAFTapps

    STUDIOCRAFTapps

    Joined:
    Feb 4, 2015
    Posts:
    102
    Sooooo... I tried implementing GPU Instancing for my TextureId parameter. I think It would've worked if it wasn't for this error I got:

    My error:
     Shader error in 'BuildingShader2': unrecognized identifier 'UNITY_INSTANCING_CBUFFER_START' at line 73 (on d3d11) 


    At:
    Code (CSharp):
    1. UNITY_INSTANCING_CBUFFER_START(InstanceProperties)
    2.             UNITY_DEFINE_INSTANCED_PROP(float, Vector1_57CF0780)
    3.         UNITY_INSTANCING_CBUFFER_END
    If I replace CBUFFER_START with BUFFER_START I get this:
     Shader error in 'BuildingShader2': unrecognized identifier 'UNITY_INSTANCING_CBUFFER_END' at line 75 (on d3d11) 


    If I replace CBUFFER_END with BUFFER_END I get this:
     Shader error in 'BuildingShader2': unrecognized identifier 'UNITY_INSTANCING_BUFFER_END' at line 75 (on d3d11) 


    "Unity is easy to learn and blah blah blah" Yeah right
     
  6. STUDIOCRAFTapps

    STUDIOCRAFTapps

    Joined:
    Feb 4, 2015
    Posts:
    102
    My bad, had to use

    Code (CSharp):
    1. UNITY_INSTANCING_BUFFER_START(InstanceProperties)
    2.             UNITY_DEFINE_INSTANCED_PROP(float, Vector1_57CF0780)
    3.         UNITY_INSTANCING_BUFFER_END(InstanceProperties)
     
  7. STUDIOCRAFTapps

    STUDIOCRAFTapps

    Joined:
    Feb 4, 2015
    Posts:
    102
    Compiled it, it works... Kinda. The set pass calls went from 1900~ to 1000. It's still a big number. Not sure how to lower it.
     
  8. Arathorn_J

    Arathorn_J

    Joined:
    Jan 13, 2018
    Posts:
    24
unityunity