Search Unity

Particle System Culling Issue, please help explain this to me

Discussion in 'Editor & General Support' started by AMO_Noot, Nov 24, 2016.

  1. AMO_Noot

    AMO_Noot

    Joined:
    Aug 14, 2012
    Posts:
    433
    Hey guys,

    So I've been running into a problem. I have a large 2D scene with lots of rain particles, and the rain particles collide on the level geometry. Naturally, this has a ton of overhead.

    So I figured I would take advantage of Unity's handy culling system, and simply just slice up that rain particle system into multiple pieces, like so:


    My understanding was this: since Unity supposedly won't render/simulate the particle systems that the camera cannot see, I'll get to effectively cut my physics collisions etc to only which section of the rain is being shown on the camera right now.

    But here's the problem: I can't get the culling to work.

    Whenever I try this method, even though only Particle system A is visible on both editor and game cameras, the overhead from B and C still exists, which means that it is still being simulated. If I deactivate the game objects of B and C, the overhead goes down.

    So, what's the deal? Is there a step to particle culling that I'm not getting? I already searched the net, but ironically most of threads about culling is about how to turn it off, not on. And the scale on all the systems is 1,1,1.
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    This is a known bug. Particle systems are not culled until they have been seen at least once. Its a bug we have had issues fixing. We are still working on a proper fix though.
    A workaround is to have all the systems visible by the camera at start and then move them in place via script or instantiate them from script at start.
     
  3. AMO_Noot

    AMO_Noot

    Joined:
    Aug 14, 2012
    Posts:
    433
    Hey Karl, thanks for the quick response! It's a relief to know that it's a known bug, at least. Hopefully it will be fixed before long, as it's a pretty big one! I'll keep the workaround in mind until then, thanks.
     
    karl_jones likes this.
  4. AMO_Noot

    AMO_Noot

    Joined:
    Aug 14, 2012
    Posts:
    433
    Hey Karl,

    I tried one of the workarounds (instantiate them from script at start) but no dice. Does the editor view affect the culling at all, or just game view? In any case, I instantiated 5 rain systems on scene load, only 1 was visible from either camera; but the other 4 were still calculating physics/rendering. :(
     
  5. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    Yes the scene view will be treated like a game camera so if they see the particle systems then they won't be culled.
    Its possible using a script still wont work until they have been seen by a camera for the first frame so that they can then receive the on culled event.
     
  6. AMO_Noot

    AMO_Noot

    Joined:
    Aug 14, 2012
    Posts:
    433
    Hmm, no workarounds working for me unfortunately on Unity 5.4.2f2

    Tried:

    - Instantiating from Script
    - Instantiating from Script in Front of Camera at scene start, then moving them by script to correct locations.
    - Placing Particle systems in front of Camera in scene, and then moving by script to correct locations at scene start.
    - Tried wildly moving particle system in front of camera and then moving it far away.
     
  7. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    Hmm. What are the settings on the particle system? I'll have to check but i believe that certain settings prevent us from using procedural calculations which mean that you get less benefit from culling.
     
  8. AMO_Noot

    AMO_Noot

    Joined:
    Aug 14, 2012
    Posts:
    433
  9. AMO_Noot

    AMO_Noot

    Joined:
    Aug 14, 2012
    Posts:
    433
    @karl_jones did any settings on the particle system prevent the culling, do you think?
     
  10. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    Yes. Only procedural particle systems really get any benefit from culling and because you are using both world space and collisions we can not use procedural mode, you won't get any significant benefits from culling. You can see that it's not procedural with the little icon:
    proc.png

    Procedural mode is something we need to provide more information on in the docs. I will work on adding something.
     
    edilbertoaq likes this.
  11. AMO_Noot

    AMO_Noot

    Joined:
    Aug 14, 2012
    Posts:
    433
    Gotcha.

    I guess I'll have to do culling myself then by having triggers turn adjacent particle systems on and off; raindrops with collision over a wide area is just too expensive otherwise.
     
    karl_jones likes this.
  12. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    You can also use the CullingGroup to do custom culling, I'm working on a blog post at the moment with further details about particle culling.
     
    AMO_Noot likes this.
  13. AMO_Noot

    AMO_Noot

    Joined:
    Aug 14, 2012
    Posts:
    433
    Sounds good! Looking forward to reading it. :)
     
    karl_jones likes this.
  14. Shawn-Halwes

    Shawn-Halwes

    Joined:
    Jul 17, 2013
    Posts:
    51
    I recently found the blog written by Karl noted in this thread.

    I am curious if there is API for the ParticleSystem component that allows us to determine if the system is in procedural mode or not? This would be useful to access both at run time and in the editor.

    I perused the documents, but did not find anything that seemed directly related.
     
  15. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    No there is nothing public or even in the C# side.For the inspector we just check certain params for each module(the ones mentioned in the blog post). What would you do if you did have access to it?
     
  16. Shawn-Halwes

    Shawn-Halwes

    Joined:
    Jul 17, 2013
    Posts:
    51
    It would allow me to do static or runtime filters of systems that may not be setup efficiently because they are not culling.

    An example would be an editor script that runs through the assets and locates the ones that would not cull for evaluation. Not all developers making particle systems will be aware of the impact of their settings on the culling and many of them will miss the tiny visual warning icon.
     
  17. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    Does this still apply? Im getting a huge amount of particle systems "alive" in my game, even when theyre no where near me. The little bubble message is not there on any ive tweaked them all so they should be cullable, but right now have 200+ alive particle systems, how do I stop them playing until I see them ? IE, why wont they cull?? Confused by that.
     
  18. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    No we fixed this quite some time ago. Are you using systems which dont support culling? https://blogs.unity3d.com/2016/12/20/unitytips-particlesystem-performance-culling/
     
  19. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    Thanks I have read that quite a few times today, great work. But I dont think Im using things that aren't cullable, if they are able to be culled the little message bubble vanishes right? Ive gone through made sure that does not appear on any particle system, so I assumed they would all be cullable. But yet still 250 of them exist all over my scene and dont go off even when frustrum does not contain them. Or maybe the message bubble is misleading, there are other things that stop it being culled?
     
  20. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    Are you making changes to them with a script? You may be breaking the culling support during play. A good way to check is to enable the bounds and see if they are moving. If it's constantly changing then culling support is disabled. How big are these particle effects? Maybe the bounds is Soo large that they are always shown?
     
  21. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    No there appears to be no script on them. I ticked bounds they are static, "resimulate" is ticked is that an issue? also "play on awake" is ticked, any issue ? I also have set them to static, not sure if that helps. They arent huge particle systems just some from pipes etc.

    Is emitter velocity - rigidbody an issue?
     
  22. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    Setting them to static does nothing for particles. Rigidbody is fine, just how we calculate the velocity of the system. Are you able to share the scene so I can take a look?
     
  23. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    Thanks! I will try but its absolutely huge!..

    edit: struggling with zipping it! Could I make a video showing everything in detail instead?

    Error compressing TAR:
    7-Zip (a) [64] 16.04 ZS : Copyright (c) 1999-2016 Igor Pavlov : 2017-03-20

    Scanning the drive:
    18320 folders, 65373 files, 26201855861 bytes (25 GiB)

    Creating archive: Z:\GDV16\GD\Temp\archtemp.tar

    Items to compress: 83693



    System ERROR:
    There is not enough space on the disk.


    0x00000001411B000B (Unity) StackWalker::GetCurrentCallstack
    0x00000001411B288F (Unity) StackWalker::ShowCallstack
    0x000000014108CA30 (Unity) GetStacktrace
    0x0000000140596DA3 (Unity) DebugStringToFile
    0x0000000140597581 (Unity) DebugStringToFile
    0x00000001412A6369 (Unity) CompressPackageTarGZAndDeleteFolder
    0x000000014103E4D3 (Unity) ExportPackage
    0x0000000141050C67 (Unity) TickPackageImport
    0x00000001410C4504 (Unity) Application::TickTimer
    0x00000001412CC349 (Unity) MainMessageLoop
    0x00000001412CDC04 (Unity) WinMain
    0x0000000141DE45A8 (Unity) __tmainCRTStartup
    0x00007FFD12981FE4 (KERNEL32) BaseThreadInitThunk
    0x00007FFD1307EF91 (ntdll) RtlUserThreadStart
     
    Last edited: Mar 22, 2018
  24. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    I made a video where I tried to show everything, maybe this helps? Much appreciated.
     
  25. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    Hi.
    IsAlive and Playing won't take culling into account in that way.
    IsAlive checks if the particle system should have any particles still alive, so have they expired yet or is the system looping. If it's looping and playing then it will always be alive.
    We don't actually have a way to check if it's culled via script, no one knew this was a thing till I wrote that blog post :D
    In 2018.1 we added automaticCullingEnabled property so you can check.

    In your video you are changing values while the game is playing, if you do this it will actually break culling as the system becomes nondeterministic, because you have different states at different points in time. So if you then change back to properties that are ok to be culled then it will no longer cull until the system has been reset(fully stopped and play).
    Here is an example of what I mean:
    I change a property which makes it not culled. I then change it back and the bounds continue to resize because they are not able to use a deterministic behavior anymore, so culling is broken even though the inspector does not show it. That's because the inspector is only telling you about your current settings, not the state of the system. So in your version of Unity, the best way to tell is with the bounds, like you say they are changing which means they do not support culling.

    culling.gif

    So are you changing any values on the systems during play? Perhaps the debug script you are using is doing it?
    Checking the bounds is only a rough guide. If you have a system that has static particles that are not moving then the bounds won't change over time, so it could still not be culled but you would not know

    Have you tried running the profiler with a deep profile, it should tell you exactly what is making things slow, down to the module. May help identify the systems that are not culled.
     
    Last edited: Mar 22, 2018
  26. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    Thanks I guess I should add the check for automaticCullingEnabled to my script (once I upgrade to 2018, still on 2017.2 since upgrading broke some assets) that may eliminate things I think are alive, but its very weird particle numbers change. So I should not have particle systems looping ? but wont they only play once and then stop ? Im fast starting to think I should use the same optimisation I do on my npcs using some form of onBecomeVisible/inVisible and maybe a cube somewhere in the particle system to trigger it.

    Also im not actually changing anything during runtime, in that demo I may have ticked or unticked somethign that broke culling on one, but not all the others. And if you watch later on in video the water in the fountain is not changing boundaries, and still isnt culled (I dont think). My debug script simply gets an array of them and lists them out.

    I will try deep profiler again but most of the time it simply points to an object called "NA" which leaves me guessing again. Much of the optimisation I need to do is plagued by this very issue, and I never understood why. No one does :) But unity keeps you guessing until lunchtime the next day before you find it.

    Thanks for all the help, this week I have optimised absolutely everything, just need to finish off particle systems to get full speed benefit. Some weird unrelated things I noticed were: character controllers are heavy on physics/cpu, even sleeping and or kinematic rigidbodies are also heavy on the physics (now trying to turn these things on just in time with a trigger), never use physics in particle systems :) and this one, particle systems are tough to cull lol... Cheers!

    PS. A great service from unity would be you pay to spend a week with some of the devs who help you fix all the niggles you cannot do, and spot optimisations etc, even as an indie Id prob put down £1000 to fix all my issues and have someone help me optimise. Or they could just do it for love lol.
     
  27. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    You read this? https://blogs.unity3d.com/2016/12/20/unitytips-particlesystem-performance-culling/ ;)
    Look at the Custom Culling at the bottom, it's exactly that.

    We already do this as part of our support packages. https://unity3d.com/learn/premium-support

    Are you able to share the project? I don't mind having a look, providing its simple to get going ;)
     
  28. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    Im now using 2018.1 but I dont see "automaticCullingEnabled " ?
     
  29. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    richardkettlewell likes this.
  30. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    oh yes it does compile sorry just VS putting red line under. The funny thing is im not sure how much this helps, I was hoping for a variable more like isCurrentlyCulled. In my script which shows all particle systems which are alive, playing and have automaticCullingEnabled it still lists 250. Now am I misunderstanding or does this mean the particle systems are going all the time even when im not looking at them ? Maybe I got too far into trying to optimise/cull particle systems and im misleading myself, I just want to know which particle systems are actually wasting time in the background when I cannot see them, and to do something about them. I dont mind doing the custom culling thing if it needs to be done but I assumed unity would do this for us.
     
  31. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    The point is that if automaticCullingEnabled is false then Unity can not automatically cull the system because it does not have a deterministic behavior. If we did automatically cull the system then this could become quite obvious to the users and/or break gameplay etc. See my blog post for further details. The point in custom culling is that some effects are ok to cull, due to them being localized, background effects etc that won't stand out if they are not updated when offscreen. Only you can make this decision, Unity has no way to know. Try adding the example script from automaticCullingEnabled to all your systems. See if the performance improves and if the particle effects look ok when going on/off screen. You can modify the script to then report if the system is currently culled for your stats.
     
  32. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    Thanks! Ok great so now all my particle systems seem to have automaticCullingEnabled as true now, so I assume when they're not in my frustrum they are now being culled. It's still misleading to know for sure though because they still all appear on my list which checks: if (p != null && p.isEmitting && p.IsAlive() && p.isPlaying), if it gets past that then it will show up in my list red if !p.automaticCullingEnabled, and none of mine are red. But, why then do they still appear in the list claiming to be emitting (and I see particleCount changes on some of them, not many but seems to go up and down by 1 or2 still) even when out of the frustrum ? I expected that as I move around and my list updates, that the list of particle systems would grow and shrink depending on which ones are in my frustrum. Very sorry to keep labouring this point but it seems to contradict itself, ie if auto culling is working (and theyre not in frustrum) why do they claim to be alive, emitting, and playing, unless all of these methods are bugged somehow? I think I read even when they're culled they will still report being alive and playing, but I assume they should not be reporting isEmitting as true. Thanks again for all the help.

    EDIT: im assuming now even when culled isEmitting wrongly returns true, and I am just trusting they are culled, since after closer inspection their particle count does pretty much stop still when they're not in the frustrum, so I will change my script to only keep them in the list if particleCount keeps changing. If that is correct then I have what I want, they're culled, and my list will show only alive ones, which will change depending on where I go in my level. Thanks.
     
    Last edited: Apr 9, 2018
  33. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    Well, the particle system is still playing and emitting, it's just not currently visible. So technically while the system is offscreen it is still playing and emitting however because it's deterministic we don't need to do those calculations until it becomes visible. when you turn and look at it then it will appear like it has been emitting and playing. Just because you're not looking at the firework, doesn't mean it's not exploding. If a tree falls in a forest and no one is around to hear it, does it make a sound ;)
     
  34. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    Hey, I found a bug in my custom culling. Here is a fix, should help quite a bit https://gist.github.com/karljj1/aa833be5c2e8a061fb1693ee0d31c915
    You don't get a culling notification until the system changes state, so you need to start the particle systems in a culled state or you won't see a benefit until they have become visible.
     
  35. marcmantraunity

    marcmantraunity

    Joined:
    May 31, 2014
    Posts:
    21
    Hi @karl_jones,

    I'm using your custom culling component for particles and I have to comment automaticCullingEnabled code to fix an error. How I can solve it correctly? I have some systems I want to use yours instead of the default Shuriken procedural system.

    upload_2020-6-18_18-53-29.png

    Thanks in advance!
     
  36. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    What version of Unity are you using?
    We added this as a feature https://docs.unity3d.com/ScriptReference/ParticleSystem.MainModule-cullingMode.html

    The error in the script is due to the field being made obsolete, it should have upgraded.
    Change automaticCullingEnabled to proceduralSimulationSupported
     
  37. marcmantraunity

    marcmantraunity

    Joined:
    May 31, 2014
    Posts:
    21
    Hi @karl_jones and thanks for your fast reply,

    I'm using 2018.4.23 version. The main reason to still use the script is to customize the bounding box. In some group of particles I can see a bigger one than what I see: Because I'm using a geometry with a dissolve, stretches billboard or things like that. For this reason, I want to adjust the BB to cull as many particles I can.

    upload_2020-6-19_9-34-31.png
    upload_2020-6-19_9-38-5.png

    If I'm using the script, what performs better? Set the culling mode to Automatic or Always Simulate?

    Seems everything goes fine now! Thanks!
     

    Attached Files:

  38. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,291
    Always simulate would be best if you are managing the culling yourself.
     
    marcmantraunity likes this.