Search Unity

Question Shader Properties per instance ?

Discussion in 'Shader Graph' started by Opeth001, Dec 23, 2019.

  1. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Hello Guys,
    sorry if my question seems redundant :p but im new to shaders stuff.
    i read in the documentation a line saying we can get a single material with single shader to set parameters like color as an instance property which means 2 GameObjects both having the same Mesh and Material can have different colors and be drawn into the same Draw Call.

    how can we set properties like the Color to an instance from Editor and Script without affecting all other GameObjects using the same material ?

    THE LINE.
    Code (CSharp):
    1. GPU Instancing only renders identical Meshes with each draw call, but each instance can have different parameters (for example, color or scale) to add variation and reduce the appearance of repetition.
     
  2. jamespaterson

    jamespaterson

    Joined:
    Jun 19, 2018
    Posts:
    401
    Search for "materialpropertyblock". The shader code itself also needs to support instanced properties itself. Good luck!
     
    Opeth001 likes this.
  3. jamespaterson

    jamespaterson

    Joined:
    Jun 19, 2018
    Posts:
    401
    P.s. this advice is based on my experience of using the standard renderer, newer lwrp / urp / hdrp may work differently.
     
    Opeth001 likes this.
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Since this is in the Shader Graph forum, indeed it should be pointed out that Shader Graph does not yet support instancing, and may never support it.

    That said part of the reason why is Unity is expecting people to use the SRP Batcher option which doesn’t use dynamic batching (merging meshes of the same material into one) or instancing (rendering multiple identical meshes with the same material, with support for per-instance properties).
    https://blogs.unity3d.com/2019/02/28/srp-batcher-speed-up-your-rendering/

    The use of material property blocks to modify per renderer material properties does not require the use of instancing, and is a perfectly good way to go about it. Especially if it’s a setting that you’ll be updating often and uniquely per-renderer. Material property blocks allow you to modify material properties with out creating new materials which reduces the memory usage.
     
    spuchals, iSinner, NotaNaN and 5 others like this.
  5. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Thanks @bgolus for these informations :)
    I’m not sure about automatic GO instancing but they are already supporting the GPU instancing if you do the rendering manually like by using Graphics.DrawMeshInstanced Function . ( it’s working for us )
     
  6. jamespaterson

    jamespaterson

    Joined:
    Jun 19, 2018
    Posts:
    401
    Thanks for the correction bgolus!
     
  7. vildauget

    vildauget

    Joined:
    Mar 10, 2014
    Posts:
    121
    If I understand correctly the official information in that link, you should avoid material property blocks to use the SRP Batcher. So material property blocks would be otherwise fine if you go for instancing instead. So I guess SRP batching means few generic shaders with possibly many properties, and many materials (per object or group of objects) with unique property values.

    Sorry for necroing this thread, but I got to shaders and shader graph now, and started research per-object properties, and thought I should point that out.
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    To be honest it's part of the SRP batcher I don't fully understand either. It seems like it's something the SRP Batcher could support without an issue (as long as you define static per-material and dynamic per-object properties separately in the shader), but I don't know of anyone who's actually gotten this to work. And actual technical implementation details on the SRP Batcher hasn't been forthcoming from Unity. That now year old blog post remains the "best" source of information and it's incomplete at best.
     
    SenseEater and shamsfk like this.
  9. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    I think they are hesitant to document it and view it as still a WIP. It's really not a complete solution for a lot of use cases atm, it requires 2020.1 beta to get there. BatchRenderGroup itself really only works well for entirely static scenes. 2020.1 has some new stuff that then allows partial updates to the data on the gpu. The api surface in total needs work.
     
  10. vildauget

    vildauget

    Joined:
    Mar 10, 2014
    Posts:
    121
    What I (re)discovered and tested before bed yesterday, though, is that with Hybrid Renderer V2, you actually get per-instance properities, without the use of property blocks or different materials. They don't mention if it works with SRP batcher, so I still have to test on a larger scale to confirm, but I would hope/belive so.

    https://docs.unity3d.com/Packages/com.unity.rendering.hybrid@0.4/manual/index.html
     
  11. vildauget

    vildauget

    Joined:
    Mar 10, 2014
    Posts:
    121
    To confirm, in my simple test scene, it all goes through the SRP batcher code path, according to SRP Batcher Profiler script, which makes CPU rendering time go from 0.70 ms to 0.45 ms. (The script can toggle SRP Batcher on/off)

    So my conclusion for per-object properties is super easy now. We can use shader graph and expose properties, and they'll automatically be per-object, easily useable from Burst-enabled systems. Oh boy, am I gonna abuse this.

    We can, for most cases, forget about converting shader graph shaders to code to introduce property blocks + code instancing. SRP Batching just works and saves quite alot of CPU time for rendering.
     
    Kalificus and Opeth001 like this.