Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Feature Request Decal performance barriers

Discussion in 'Universal Render Pipeline' started by JSmithIR, May 14, 2023.

  1. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    111
    Does anyone have any insight into how to use large number of decals in URP? There does not appear to be a way to instance hundreds of decals without huge performance loss. This ability is central to our project. If compute shaders can draw hundreds of thousands of gameobjects that share the same material, and can vary them via material property blocks - and meanwhile hdrp can instance decals via the vfx graph- surely there is a way in IRP to render decals in mass quantities? Currently in my URP project using 100 decal projectors drops fps from 112 to 59 with an rtx4080!! Surely something is wrong here
     
  2. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    4,971
    What are your decal settings?
     
  3. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    111
    Technique: screen space
    Normal blend: Medium
    Use Gbuffer: true
    Max Draw Distance, 1000

    decal shader uses gpu instancing
     
  4. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    4,971
    1. If you are on a non mobile platform try dbuffer maybe instead of screen space.
    2. Reduce the draw distance. I highly doubt you can see much at 1000 meters away.
     
  5. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    111
    Why would the draw distance be an issue? My project needs hundred of decals within the camera view at a time. As far as dbuffer versus gbuffer, I don’t think that is accounting for the bigger issue here. Why can’t these be instanced so that thousands can be drawn? I am losing 60fps over 100 - there is something fundamentally wrong
     
  6. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    4,971
    If I recall correctly the shader becomes more and more heavy the further the distance, and next to this more stuff gets rendered of course.
    You did not specify it's an instancing issue, how much more draw calls does it make in the frame debugger?

    For the different rendering technique, some are way faster on different hardware, since it renders completely different. Worth a try for sure
     
  7. ciaranhappy1

    ciaranhappy1

    Joined:
    Oct 22, 2018
    Posts:
    15
    Might it be possible to, at a large distance (say over 400 metres away) replace the projected decal with a potentially easier to render, old style flat plane decal? At that kind of distance you can probably get away with being fairly quick and dirty with lining the plane up with the wall, and based on what I'm reading in this thread it sounds like a simple transparent shader might be easier to render at that distance than a decal. You might be able to make a script that sets this up for all the projector decals on start (or at any other time), so if your smart it shouldn't be too much of a hassle to set up a new decal either.

    Dunno if its a reasonable solution in your case (All i know is you for some reason need to render huge amounts of decals at once), but its an idea atleast.
     
    DevDunk likes this.
  8. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    761
    I remember that documentation (performance part) says URP decals don't support SRP Batcher because the use of material property blocks.


    If the decals in your Scene use the same Material, and if the Material has the Enable GPU Instancing property turned on, Unity instances the Materials and reduces the number of draw calls.

    To reduce the number of Materials necessary for decals, put multiple decal textures into one texture (atlas). Use the UV offset properties on the decal projector to determine which part of the atlas to display.


    Hundreds of URP decals shouldn't be a problem for rtx4080, so I think draw calls of those decals caused a CPU bottleneck. You can try following the documentation to enable GPU Instancing for decals.
     
    ciaranhappy1 and DevDunk like this.
  9. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    111
    I have gpu instancing enabled and can see that in the stats that they are being instanced, yet the performance hit is still there. Of course no reply from people at Unity Technologies I reached out to. Will post screenshots tonight
     
  10. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    761
    Is the bottleneck on the CPU side? You can confirm this in GPU Profiler.
     
    JSmithIR likes this.
  11. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    111
    Thanks I will send info when I get out of work
     
    wwWwwwW1 likes this.
  12. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    111
    So as it turns out, I am not sure if instancing is actually working... When I select "enable gpu instancing" on the decal material, the number of batches and setpass calls does not reduce. It remains a 100 batch increase when I enable to decal group. When I deselect "enable gpu instancing" there is no visible change in performance. I am confused because it states here: https://docs.unity3d.com/Packages/c...ersal@12.0/manual/renderer-feature-decal.html "URP supports the GPU instancing of Materials. If the decals in your Scene use the same Material, and if the Material has the Enable GPU Instancing property turned on, URP instances the Materials and reduces the performance impact."

    I don't know a whole lot about profiling, but in the profiler tab I visibly see a large jump in the CPU Usage graphs and GPU usage graphs when I enable the group of 100 decals
     
    wwWwwwW1 likes this.
  13. DevDunk

    DevDunk

    Joined:
    Feb 13, 2020
    Posts:
    4,971
    You can check in the frame debugger why it's not batching.
    Also make sure to enable gpu instancing in the urp asset
     
    ciaranhappy1 and wwWwwwW1 like this.
  14. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    111
    So in the frame debugger, for each decal draw call it says "Why this draw call can't be batched with the previous one: objects have different materials." Yet each decal has the same material, and that material has "enable gpu instancing" turned on....
     
  15. PieterAlbers

    PieterAlbers

    Joined:
    Dec 2, 2014
    Posts:
    236
    I have been following this closely.
    What Unity/URP version are you using @JSmithIR?
     
  16. Allan-MacDonald

    Allan-MacDonald

    Joined:
    Sep 21, 2015
    Posts:
    112
    As long as you're not using GPU instancing (breaks SRP batcher) and you're using the shader they provide you should be fine? When I last looked at it the decals were batching together perfectly, I could have 30+ and they're all batched together. I'll do a test tonight.
     
  17. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    111
    Mine does not batch at all whether I use SRP batcher or GPU instancing.... @PieterAlbers I am using Unirt 2021.2.14f1 and URP 12.1.5
     
    PieterAlbers likes this.
  18. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,549
    You can grab this:
    https://github.com/Unity-Technologies/SRPBatcherBenchmark

    Add only the SRPBatcherProfiler.cs file to your project (don't need anything else), then add a GameObject to your scene and add the SRP Batcher Profiler component. Enter Play Mode. Toggle display of that info with F9. Unless things have changed, your Stats window actually doesn't show useful info about batching when using an SRP - you need to use that profiler to see. More info about SRP batching is here, though the article is pretty old it's still worth a skim:
    https://blog.unity.com/engine-platform/srp-batcher-speed-up-your-rendering
     
    ciaranhappy1 and JSmithIR like this.
  19. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    111
    Yeah, thanks I will do that soon. But in the meantime, I think we can agree that 100 decals should not drop the fps from 112 to 59 on an rtx4080. It is not instancing, clearly. Also, given the fact that turning GPU instancing on and off, and toggling on and off the SRP batcher, is having absolutely no impact on performance. To me this makes it very likely that no batching is working in any case
     
  20. ciaranhappy1

    ciaranhappy1

    Joined:
    Oct 22, 2018
    Posts:
    15
    Your right - 100 decals, though an unusually large amount, should not tank a 4080 that much. Something weird is definitely going on.

    Have you checked whether GPU instancing is working with objects that arent decals? If its not, then the issue or bug is probably with the instance rather than the decals.

    Also its a stretch at this point but worth checking: are the decals marked as static? If so, then the instancing probably wont work right since SRP generally wants to batch static objects, and the batching and instancing dont play well together
     
  21. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    111
    They are not static, and gpu instancing IS working with other objects
     
    ciaranhappy1 likes this.
  22. Allan-MacDonald

    Allan-MacDonald

    Joined:
    Sep 21, 2015
    Posts:
    112
    Are you using urp decal shader? And no gpu instancing on it? I’m not sure if you can be using gpu instancing on anything at all while using srp
     
  23. JSmithIR

    JSmithIR

    Joined:
    Apr 13, 2023
    Posts:
    111
    Hey Allan, yes I have tried all the variations- with gpu instancing enabled and sep batcher off, and also tried no gpu instancing with srp batcher on. Either way it wont batch. Other objects batch normally
     
  24. Allan-MacDonald

    Allan-MacDonald

    Joined:
    Sep 21, 2015
    Posts:
    112
    Hey, how are you checking the batching? The Stats window in URP doesn't work, you need to check the Frame Debugger or just measure .ms in the profiler now.