Hello friends
I’m wanting to build a runtime occlusion culling system, however: how do I do this? Specifically, how do I tag objects to be culled by a certain camera?
Thanks
Hello friends
I’m wanting to build a runtime occlusion culling system, however: how do I do this? Specifically, how do I tag objects to be culled by a certain camera?
Thanks
The expression ‘biting off more than you can chew’ springs to mind! If you can’t figure out how to tag objects for occlusion by a camera, how do you expect to be able to do the difficult parts efficiently?
Or maybe I’m just being too pessimistic.
I’ve worked on occlusion culling before, mostly in webgl.
However, I do not have the specific knowledge of how to hook into camera rendering in unity specifically.
OnWIllRenderObject() looks promising, but this requires a monobehavior to be attached to every renderer that I wish to be occluded, which isn’t the funnest.
Also, I know that the new SRP supports custom culling, but I’m sadly stuck with the standard pipeline, at least for now
Why do you want to build a custom occlusion culling system ? Are you un-happy with the existing one ?
I’m curious.
I could imagine several way of doing an occlusion culling system for a camera with raycast and stuff but i’m pretty sure it would be less optimized than the existing system.
to use the existing occlusion culling system just go in the inspector when selecting your camera
You should see a “occlusion culling” checkbox. Once checked, you would want to select specific culling masks (default is set to everything).
Now, your camera will only render the object of this specific layer, and those object would be rendered only if they are in the frustum of the camera
To answer your question then, one approach would be to assign the objects to a layer and then set the cullingMask property in the camera.
https://docs.unity3d.com/ScriptReference/Camera-cullingMask.html
My world is split into chunks, and during building these chunks are exported into prefabs. However umbra does not support this of course. And even if I just used scenes, umbra doesn’t seem to support additive scenes, unless I wanted to occlusion cull the entire world at once (resulting in a very large file)
Sorry i did not understand your question.
You have a problem with shadows ?
Can you rephrase and be more specific ?
I want to build my own culling system. Ignoring the intricacies of all of that, my question is simply how do I control which renderers are visible for specific cameras?
SRP has this: https://github.com/Unity-Technologies/ScriptableRenderPipeline/wiki/SRP-Culling
But I’m not using SRP
I’m curious about this too. Does anyone have any answers?
You could use the CullingGroup API. I believe it was meant more as a way to optimize or trigger certain behavior based on a specified bounding sphere’s visibility with a camera and less with optimizing renderers. For example Weatley from Portal 2 waiting for you to look away before he would do something.
So while I don’t think it was meant to fully replace the built-in occlusion culling system, it can in a pinch.
What I’m looking for is a way to control the visibility of meshes, as opposed to a way to check if a certain sphere is visible, which is what culling group does
Throw the bounding boxes of your meshes into an octree and use GeometryUtility.CalculateFrustumPlanes along with GeometryUtility.TestPlanesAABB (or a custom Bounds-FOV intersection method), if you want to roll your own solution.
Right. I understand how to detect whether a mesh should be visible for a specific camera. But my issue is what to do after that: how do I manually control the visibility of a mesh for a specific camera?
Do I hook into onPreRender disable / enable meshes, then hook into onPostRender to re-enable them? This seems like a slow approach
On that note, it would be super duper amazing if it was possible to easily declare an object as “invisible”, including all children. This would allow hierarchical culling to be done easily. Instead, the only way as far as I know to do this is to search for all components of a certain type, then disable all renderers, one by one. In other words, slow. Of course the renderers could be cached, so that’s good! I guess the main solution would involve caching each renderer at the beginning, then enforcing any new renderers being added to register itself.
Whoops, my fault. Sometimes i expect ppl know very little, sorry.
What i generally try to do is have less GameObjects and draw meshes with Graphics.DrawMesh().
That feels like working against the engine, but i can minimize the GameObjects i need without many drawbacks.
It pretty much depends on what you do, but it helps to save performance where it would otherwise simply be wasted.
I’ve found that’s a good solution for things like trees, for example, since it’s essentially a single “renderer” object deciding which trees to render and such. However my goal for this occlusion culler is to cull static meshes in the scene without needing to scan during edit time. Thus, I’ll sadly need to keep the individual gameobjects intact.
Well then i guess your best bet is to cache the renderers, as you already mentioned.
Another idea that comes to mind would be to remove the renderers from the GameObjects at runtime and use Graphics.DrawMesh() to render them. Probably add a bool flag to each GO and early exit methods like Update() depending on that flag. Kind of a makeshift way to disable those GO’s. I have never tried that and i already feel dirty for thinking about it…
Hey, it’s okay to think dirty thoughts sometimes but yeah I’m probably going to experiment with caching :))
Josh, did you ever find the right answer for this?
I have sadly not arrived at a solution