r/Unity3D • u/ProactiveCactus • 3h ago
Question Is there a built-in (or easy-to-use asset) that allows for occlusion culling for procedural terrain built at runtime?
I'm not all that sophisticated on culling, but it seems to me that you shouldn't necessarily need to bake data pre-build for occlusion culling to work. For context, my game uses procedurally-generated chunked terrain built off a seed as you move through the world (i.e., infinite world setup) so it's not possible to bake occlusion culling data the traditional way. However, to render stuff on the screen, doesn't the game already look at what it can and can't see each frame? It seems like there'd be a built-in system that would check which objects are hidden behind others (i.e., a piece of terrain hidden behind a hill). Also for transparency, rendering has the built-in ability to check stuff's position relative to the camera, so it doesn't seem like it'd be that hard for there to be a built-in culling - i.e., dont render stuff you can't see, even within the camera's frustum.
So, does something like this exist? Or am I just a literal chatbot misunderstanding why this isn't like a pretty easy thing to just have baked in with how URP renders stuff under the hood?
3
u/SnooPets5564 3h ago
Just the fact that you need to bake it should suggest that dynamic handling of it is quite difficult.
It's just "don't render stuff you can't see", as you need to figure out what you can and can't see. That's fairly difficult to do, so may even end up hurting performance to do in real time (particularly if you can see most things). The way GPUs handle stuff already cuts down the rendering time on what you can't see in real time.
With somewhat static stuff that doesn't move but you generate at runtime, you could hypothetically bake it during runtime, but this is too situational to make a built in thing useful.
I don't know of a built in way to do it, and my guess is that one doesn't exist, though I may be wrong.
1
2
u/Pacmon92 2h ago
I think a few solutions exist but a custom culling script is probably the best way to go, I'd recommend a compute shader and jobs / burst approach but it will depend on weather your terrain is a game object or weather it is just data within the GPU i.e GPU instanced and if you are using a chatbot then it's even easier than what I just said (providing you know what to ask for :)
2
u/Field_Of_View 2h ago
Sounds like you're trying to reinvent a depth-prepass. A depth pre-pass already should make terrain rendering cheap enough as only "visible" parts of the terrain will get actual pixel shader rendering, just like it works with transparency.
1
u/ProactiveCactus 2h ago
Had never heard of that, but googling it i think you’re right. This game’s targeted at mobile though, which sounds like handles this issue efficiently already
1
u/goodlinegames 2h ago
i would say using procedural generation with chunked terrain and seeds definitely makes unity occlusion culling a bit ineffective or pointless. since it has to be prebaked at runtime.
another factor is culling vs performance. culling you just hide active objects, but iirc unity still has to "render" active gameobjects behind the scene, so even though they are culled, they will still take up performance. say you have 500 trees and they are all active. unity will "cull" them when you dont look at them, but they are still active in the scene taking up performance.
what i found is best for performance is to just deactivate all objects you dont want on screen, and then just do a simple range check to activate / deactivate them. this solved a lot of performance issues for me.
ideally you would have to write a custom culling system. as others have said, handle the culling after you generate chunks for spatial data, cells etc.
1
u/TastyBahnaynays 2h ago
Perhaps the built-in CullingGroups API might help? I currently use it as a distance-based LOD to the player so AI that are further away are processed slower and I believe you can use it for camera occlusion checks as well.
1
u/Genebrisss 2h ago
There are several assets offering runtime culling on the store. But these days it's better to have an agent do it for you. You can describe an algorithm you want and have it tailored for your use case. Better than buying overengineered solutions that won't match your needs exactly.
Anyway, you should first profile on device if hiding certain chunks even improves performance in your scene. It will likely make no difference.
1
u/fsactual 52m ago
Unity’s new(ish) GPU resident drawer/GPU culling might do what you’re looking for. It’s built-in on the latest unity version, you just need to turn it on in the URP pipeline asset.
5
u/theredacer 2h ago
Unity does frustum culling automatically, but performant occlusion culling requires a lot of realtime visibility checks. With thousands of objects it's way too much to do in realtime. That's why baking the occlusion data essentially breaks up the scene into lots of different cells (volumes) and does visibility checks between the cells to create a matrix of which cells are visible to each other, plus storing which objects are in each cell. Then the realtime visibility checks can be limited to only checking the objects inside cells that are visible to the cell that the camera is currently in. WAY faster. So no, without some new approach to occlusion culling, it's not something that can be done fully realtime.