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

[SOLVED](LWRP) i can't change a material property without breaking batching ?

Discussion in 'Graphics Experimental Previews' started by Gruguir, Jan 11, 2019.

  1. Gruguir

    Gruguir

    Joined:
    Nov 30, 2010
    Posts:
    340
    (UT 2018.3 /LWRP 4.6.0) In standard RP i used material property blocks to modify properties at runtime.
    Now batching breaks as soon as i change a property value. Is there a specific way to do that ? I'm lost with SRP and wasn't able to find infos on this topic.
     
    Shorely likes this.
  2. Andre_Mcgrail

    Andre_Mcgrail

    Unity Technologies

    Joined:
    Dec 9, 2016
    Posts:
    244
    Some properties are wrapped behind shader features(shader keywords), this can lead to using an actual different shader all together if changed meaning even using a MaterialPropertyBlock will not work as they will be different shaders. This will only happen if you are changing any boolean or adding a texture and the other material has no texture applied.

    Do you have an example of what you are changing via the MPB and which LWRP shader?
     
  3. Gruguir

    Gruguir

    Joined:
    Nov 30, 2010
    Posts:
    340
    @Andre_Mcgrail
    Thanks for your support. I've done some more tests. It looks like in 2018.3 i can't keep my meshes to batch as soon as i change a property value. I made a test with simple cubes sharing an LWRP unlit material (with a checker texture), changing only the "Color" property value at runtime. Each cube is then drawn separately.

    Here is the code :

    Code (CSharp):
    1.  
    2. MaterialPropertyBlock props = new MaterialPropertyBlock();
    3.  
    4.         foreach (GameObject cube in cubes)
    5.         {
    6.             float r = Random.Range(0.0f, 1.0f);
    7.             float g = Random.Range(0.0f, 1.0f);
    8.             float b = Random.Range(0.0f, 1.0f);
    9.  
    10.             rend = cube.GetComponent<Renderer>();
    11.             props.SetColor("_Color", new Color(r, g, b, 1f));
    12.             rend.SetPropertyBlock(props);
    13.         }
    14.  
    But if i do the same test in UT 2019.1.0.a13/LWRP 5.2.3 with the 'SRP Batcher' experimental feature then the cubes share the same draw pass, without using MPB, simply calling "rend.material.SetColor("_Color", new Color(r, g, b));".

    I didn't see the SRP Batcher option in UT 2018.3/LWRP 4.6.

    My results FWIW :
    • In any case (2018.3/2019a, and latest matching LWRP) using dynamic batching it breaks
    • In 2019 i can use 'material.SetColor' with SRP Batcher on, (with GPU instancing ticked or not) to get all cubes drawn all at once. 'Batches' keeps increasing in Game stats, but 'Saved by batching' gives me a negative number.
    Honestly i'm not sure where i may hit a bug or misunderstand/do some mistake.

    I work on a mobile VR project and i'm worried of seeing game state's batches increase even if lowering setpass calls.

    Maybe i should move back to standard RP as i'd like to stick to 2018 LTS for my project and obviously some LWRP features/fixes won't reach it.
     
  4. phil_lira

    phil_lira

    Unity Technologies

    Joined:
    Dec 17, 2014
    Posts:
    584
    If you can submit your project as bugreport we will gadly take a look at why batching is breaking when not using SRP Batcher.

    As for the SRP Batcher it will not be backported to 18.3. In fact since LWRP is experimental in 18.3 we will not give support to it in 18.3 LTS version. If you can't update to 2019 I'd recommend sticking with Builtin render pipelines.
     
  5. Gruguir

    Gruguir

    Joined:
    Nov 30, 2010
    Posts:
    340
    phil_lira likes this.
  6. arnaud-carre

    arnaud-carre

    Unity Technologies

    Joined:
    Jun 23, 2016
    Posts:
    97
    Hi!
    I agree our term "batcher" is quite confusing because we have several of them ( we may improve terminology ). From user point of view there is "Dynamic" and "Static" batching. From the engine point of view there is an internal "batcher" that is trying to reduce the SetPass calls count.
    Dynamic batching was made to reduce the number of "DrawCalls" (for platform where DrawCall is CPU heavy)
    Static batching was made to reduce the number of "SetPass"

    Regarding "static or dynamic" batching, batch are broken if you're using Material Property Block ( because basically we have to internally call SetPass ). Seems strange that you noticed a regression here ( I mean, MPB usage should always break the batch to my knowledge. You can check what the Frame Debugger say about it )

    Now about SRP batcher. It's a new rendering inner loop that try to minimize the SetPass call, by not calling it if Material change. That is, if you're using rend.material.SetColor("_Color", new Color(r, g, b)); , you'll get full speed with SRP batcher because all cubes will be rendered without calling any SetPass in between. ( You still have one drawcall per cube, but drawcall is almost free on modern hardware. Only SetPass is costy). To sum up, standard rendering inner loop call SetPass for each new Material. With SRP batcher, the inner loop call SetPass only for each Shader. ( you could have 1000 different materials in a scene, you will run at full speed with SRP batcher)

    At the end, what to chose? I would say you have to look at profiling numbers ( not FPS ). I highly recommend you to use "miniprofiler.cs" c# script helper, more details and download here: https://forum.unity.com/threads/srp-batcher-in-2018-2.527397/#post-4099828. With this, you can see the rendering time and try to see what is the best option for your game.

    Last but not least, you said you're working on a VR game. I'm afraid currently SRP batcher does not support VR. ( so in VR mode, even if you switch SRP batcher ON, standard SRP rendering code path is used)
     
  7. Gruguir

    Gruguir

    Joined:
    Nov 30, 2010
    Posts:
    340
    @arnaud-carre that helps a lot. I have yet to try the miniprofiler utility. I'll stick with standard rendering pipeline for that project (and benefit from 2018 LTS). I indeed mixed batches / draw mesh terminologies, however i guess the bug report case i sent could be relevant because activating gpu instancing and changing color with MBP each cube seems to be drawn separately in the frame debugger (multiple RenderLoop.Draw) ?
     
  8. arnaud-carre

    arnaud-carre

    Unity Technologies

    Joined:
    Jun 23, 2016
    Posts:
    97
    hi,
    By default, Unity GPU instancing only supports object transform to be instantiated. In your example, the cubes can't be GPU instanced using one draw call because of their different colors.

    If you want a new property to be instantiated (such as "_Color"), you have to tweak your shader using UNITY_INSTANCING_BUFFER_START /STOP declaration.

    You can refer to this page for details: https://docs.unity3d.com/Manual/GPUInstancing.html
    It explains how to GPU instance a "_Color" for instance
     
  9. Gruguir

    Gruguir

    Joined:
    Nov 30, 2010
    Posts:
    340
    @arnaud-carre hi, i made the false assumption that those properties were instanced because of the 'Enable GPU Instancing' checkbox... I was not able to modify/clone the LWRP shader directly, but the example shader in the GPUInstancing doc works fine. I'm not used to shader code (mainly using Amplify Shader). I gathered a lot of infos, thank you all for your help :)
     
  10. Ledrec

    Ledrec

    Joined:
    Sep 10, 2014
    Posts:
    9
    Were you able to get them on the same batch? Idid what arnaud said and my dynamic batch is still broken