Search Unity

Decals Material Instancing not working

Discussion in 'High Definition Render Pipeline' started by ratuspro, Apr 18, 2022.

  1. ratuspro

    ratuspro

    Joined:
    Apr 5, 2015
    Posts:
    17
    Hello,

    I've just started working with decals and I've come across a situation that requires the use of multiple instance of the same decal (with the same material) each one with their own color set through a script. However, seems like I can only modify the base material properties and not the material's instance properties. Thus making all the decals assume the same color.

    Does Unity 2021 LTS decals support material instancing? If not, is there another way to set each decal's material properties individually?

    Thank!
     
  2. Nstdspace

    Nstdspace

    Joined:
    Feb 6, 2020
    Posts:
    26
    Hi, I just uploaded a video on this topic. I'm using URP there but the problem is the same.
    You can find the key documentation entry here.

    The URP (and HDRP) decal projector's material is not copied into a new instance when instantiating the prefab, which is usually the case for normal materials on mesh renderers in prefabs.

    (Also I assume that you already edited the default decal shader to accept colors? Because the default shader does not. See the video for more infos.
    Edit: Or does the HDRP decal shader accept colors?)

    I did not find a way to fix that in the editor (apart from recreating the material several times) but at runtime you can create a new instance of the material and change its color:

    Code (CSharp):
    1. var decalProjector = GetGomponent<DecalProjector>();
    2. decalProjector.material = new Material(decalProjector.material);
    3. decalProjector.material.SetColor(ref, someColor);
     
    Last edited: Apr 20, 2022
  3. ratuspro

    ratuspro

    Joined:
    Apr 5, 2015
    Posts:
    17
    I'm using the HDRP and I experience the same problems. The decals materials even when using prefabs are not instantiated.

    Since I'm only trying to modify the material at runtime, the solution you presented works perfectly!
    Thanks!
     
  4. Hypertectonic

    Hypertectonic

    Joined:
    Dec 16, 2016
    Posts:
    75
    I stumbled upon this issue when trying to use decals for projecting eyes and mouths on my characters and was stumped on it, thanks for the info! Packages has made it really hard to navigate the Unity docs...
     
  5. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    113
    But this breaks gpu instancing... you will not get batching with this method...
     
  6. Nstdspace

    Nstdspace

    Joined:
    Feb 6, 2020
    Posts:
    26
    I'm not too familiar with the frame debugger, but it seems that you are right: It shows me an entry of "Draw Mesh" for each decal projector in the scene using the code above:

    upload_2023-6-5_1-1-8.png

    Interestingly enough, the same thing happens when I do not recreate the material (I.e, do not execute line 2 in the snippet I posted above). The same thing happens if you use an instance of the original ShaderGraph/Decal shader (without the modification for the tint).

    Am I missing something? Do you know how to fix instancing in the base case and maybe also for the multi-color case?
     
  7. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    113
    Have you checked the stats menu when the game is in play mode (as opposed to the frame debugger which captures just one frame)? I noticed that for a split second when you make a change to the material used by decals, it will create a draw call for each decal, but then immediately drop back down to 1 draw call total for all decals. Not sure why instancing does not work at the exact moment a change is made to the material. Perhaps the frame debugger is analyzing a frame at such a moment? Have you checked that the material on all the decals has "gpu instancing enabled" checked? Those are the first two things I would rule out. Let me know
     
  8. Nstdspace

    Nstdspace

    Joined:
    Feb 6, 2020
    Posts:
    26
    I checked back and you are right - I forgot to enable instancing on the material. Indeed instancing works without and does not with recreation of the material (for obvious reasons).
    I'm not sure if there is any better way to handle this.

    A side question though, what are you trying to achieve? Are you building something with thousands of decals?
    From the docs about GPU instancing:

    So, I'm not sure if instancing will save you in such a case. Are you experiencing performance problems without instancing? I would suggest telling more about your concrete use case (maybe in a new thread), maybe there is another solution to your performance problem (if you have one, otherwise I just wouldn't bother with instancing at the moment).
     
  9. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    113
    Hmm I wonder why they created a gpu instancing option for the decal system then. Genuinely curious, not being sarcastic
     
    Last edited: Jun 6, 2023
  10. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    113
    I dont think the decals are as simple as a cube mesh with a lit/unlit shader applied to them, for example. For one, decal projectors are not meshes, ie they do not have mesh component. If you look through the URP package scripts for decals, you can see that they are actually quite involved. I have noticed a significant performance difference with instancing on and off for large number of decals.
     
    Last edited: Jun 6, 2023
  11. Nstdspace

    Nstdspace

    Joined:
    Feb 6, 2020
    Posts:
    26
    Interesting.

    Well Instancing is a generic material property, they didnt "create it for decals" explicitly. A material also does not know on what geometry it will be used.

    You can check in the frame debugger how many vertices are rendered in one draw call.
     
  12. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    113
    Okay man but look at the scripts that handle the decal draw call system. They did a lot of work to make instancing of certain property such as tiling and offset work for decals. It was not something that just worked for decals because it already was a thing for materials. You are incorrect
     
  13. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    113
    I also suggest you look up the type of decals and how they work - for example mesh decals