Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice

Question Deactivating decal projectors causes big CPU spikes

Discussion in 'High Definition Render Pipeline' started by mgeorgedeveloper, Feb 9, 2024.

  1. mgeorgedeveloper

    mgeorgedeveloper

    Joined:
    Jul 10, 2012
    Posts:
    324
    (Unity 2022.3.19 LTS)

    When I disable a large number of game objects simultaneously via SetActive(false), this usually causes no issues at all... but if the game objects include decal projectors, we have two problems:

    1. It burns vast amounts of CPU time to deactivate the objects.
    2. It allocates 100s of MB of memory (GC Alloc).

    Here is a test case where I'm deactivating 5000 game objects which happen to contain decal renderers... it takes nearly 1s to complete and allocates 300MB of RAM.

    Does anyone know how to solve this or work around it? Why do decal projectors hate being switched off?

    Thanks!

    spike-when-disable-decal.png
     
    Last edited: Feb 9, 2024
  2. reij

    reij

    Joined:
    Oct 14, 2018
    Posts:
    17
    Couldn't you just fully fade the projector? This way it would be invisible. Just a workaround idea. Or try to set the Component on the element '.enabled' to false if it is about the number of total decals
     
    Last edited: Feb 10, 2024
  3. mgeorgedeveloper

    mgeorgedeveloper

    Joined:
    Jul 10, 2012
    Posts:
    324
    The .enabled approach is the same - since the time spent is in the DecalProjector.OnDisable() callback (see screenshot), so the manner of disabling makes no difference.

    Unless there is some known work-around or fix, indeed I will need to simply keep all decals active and rely on their fade distance. Still doesn't sit that well with me that in a large open world, we might have 100K decal projectors sitting around when they could in theory be completely deactivated at game-object level.
     
  4. antoinel_unity

    antoinel_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    261
    Hello,

    I looked at the code and there is a FindIndex() in the OnDisable of the DecalProjector, the find is run on a list that contains the decal instances in the scene, so it scales quadratically with the number of decals when you disable all of them at the same time.
    Additionally, a lambda is used in the FindIndex which generates GC alloc for every call of the lambda (the call number also scales quadratically).

    I made the fix but it'll take a few weeks to reach the 2022 LTS so I have attached a patch if you want to fix it locally. Note that the issue only happens in the editor so at least it shouldn't cause any spike in a standalone player.

    I've also noticed that the Gizmo rendering performance is fairly bad, but that's much more complicated to fix, so I'll keep that for later :)
     

    Attached Files:

    halley likes this.
  5. mgeorgedeveloper

    mgeorgedeveloper

    Joined:
    Jul 10, 2012
    Posts:
    324
    Excellent, thank you!
     
  6. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,412
    I know this is the HDRP forum, but is there a similar issue in the setting of alpha for URP, maybe common code? Reading the patch doesn't seem like it would be a shared cause.

    I noticed in profiling that setting alpha for fading out footprints was excessive, so I only think about fading every N frames.