GPU Occlusion Culling without baking and raycasting

Deprecated.

https://www.youtube.com/watch?v=6VjaaLEiYa0

GDOC is a dynamic GPU occlusion culling solution that increases FPS by hiding objects that are not visible by the camera, drastically reducing draw calls.

Compared to the built-in occlusion culling, GDOC works at runtime and doesn’t need baking.

Features
— No baking, works with procedurally generated or streamed scenes
— No raycasting, doesn’t need colliders
— Supports dynamic occluders and occludees
— Most of the work is done on GPU
— Culls shadow casters for 1 directional light
— Supports LWRP
— Supports VR multi pass & single pass (non-instanced)

Testing scene: Viking Village City
Made from assets from the Viking Village demo:

MeshRenderers: 111k
MeshFilter triangles: 670kk
Particle systems: 18k
Point lights: 6k (no shadows)

The scene is generated at runtime, nothing is baked.
All meshes cast realtime shadows from 1 directional light that moves around the scene.

Comparison in editor:


It’s not really fair because scene view kills the performance.
Check out the video to see how it works in builds.

Requirements
Supported platforms: DX11 on Windows x64
Not supported yet: Vulkan, HDRP, Linux/Mac, consoles
Won’t be supported: OpenGL, Metal, mobile devices

Best practices
To achieve the best results with GDOC, make sure:

  1. Scenes are big and have many objects that can be potentially occluded (like in the demo scene)
  2. Objects exist in the scene hierarchy as MeshRenderers or other supported components
  3. You have a Directional Light with realtime shadows
  4. The number of draw calls is high and seems to be the main bottleneck

You can PM me in case you’re not sure if it will work well for your game

Purchase GDOC on the Asset Store: GDOC — Dynamic GPU Occlusion Culling | Utilities Tools | Unity Asset Store

Download demo build:
https://drive.google.com/file/d/1BIoSZBDR1B0B5TJJTRxal7uptgWFNuCp

Join Discord
Bearroll

12 Likes

tip: you should compare it with Unity defaut oc.

1 Like

Built-in OC doesn’t cull shadow casters, so if you have sun with realtime shadows, it’s not a competitor
Check out this screenshot:


It culls things fine for regular rendering, but does nothing for the shadow pass
And it leads to 1500+ extra drawcalls that contribute nothing to the final picture

Same situation but with gDOC (to be named… :smile: ):


And you see that all shadows that can’t be seen by the camera are disabled 8)

6 Likes

Very interesting, hope to see your OC soon on the store!

1 Like

First post updated with a new demo scene — it has more than 100000 mesh renderers with realtime shadows

1 Like

Oh boy have I got a scene to test this out on for YOU. :smile:
I’m working on a huge scene for a real world city building project with millions of tris visible almost every frame and full of geometry not optimized for an interactive Unity environment. Our standard baked occlusion culling isn’t really doing the best job, we think, so I’m always on the lookout for new solutions.

I’d love to test this ASAP!

2 Likes

@drcrck does this support Multiplayer/multi cams/display?

I’m afraid it can’t optimize your scene for you. If baked OC doesn’t improve performance, this one can’t as well. Can you show some screenshots of your scenes?

No, it currently supports only 1 non-vr camera. More features will be added later.

1 Like

Hi,

Great work!
Is it compatible with something like vegetation studio which already uses gpu ?

1 Like

Looks interesting!

I have a game where the whole world is made of dynamic chunks, which are itself set together to one mesh from voxels, some just cubes others meshes.

I can either set each chunk to be static, or turn that off and have all materials gpu instanced, both works fine.

I have a Problem with the Performance (each chunk is 10x10x10 blocks) when viewing distance gets higher, could this help in my case, too?

I would really like to give it a try if you are unsure and give you Feedback :slight_smile:

1 Like

No, but I need it too, so I’ll add it later

You can easily test this manually: disable chunks which are inside the camera frustum, but occluded by other objects (i.e. can’t be seen by the camera). Are there such chunks? Does disabling improve performance?

1 Like

I once tried this myself, but I do not know if I did it right.
I realized no big change if I do this or not:

    private void CheckChunksVisible()
    {
        // https://discussions.unity.com/t/659421
        //https://answers.unity.com/questions/8003/how-can-i-know-if-a-gameobject-is-seen-by-a-partic.html

        Plane[] planes = GeometryUtility.CalculateFrustumPlanes(Camera.main);
        foreach (var chunk in ChunkManager.Chunks)
        {
            //if (chunk.Value != null && chunk.Value.FlaggedToUpdate || chunk.Value.FlaggedToRemove) {
            chunk.Value.GetComponent<Renderer>().enabled = GeometryUtility.TestPlanesAABB(planes, chunk.Value.GetComponent<Mesh>().bounds); // oder chunk.ChunkCollider oder chunk.GetComponent<MeshCollider>
        }
    }

In the player’s update method:

            Vector3 screenPoint = Camera.main.WorldToViewportPoint(targetPoint.position);
            if (screenPoint.z > 0 && screenPoint.x > 0 && screenPoint.x < 1 && screenPoint.y > 0 && screenPoint.y < 1)
            {
                currentGazeTimeInSeconds += Time.deltaTime;
                if (currentGazeTimeInSeconds >= holdGazeTimeInSeconds)
                {
                    currentGazeTimeInSeconds = 0;
                    CheckChunksVisible(); // todo Thread? StartCoroutine?
                }
            }
            else
            {
                currentGazeTimeInSeconds = 0;
            }

I could do this with StartCoroutine. I just don’t know if the method CheckChunksVisibleis useful this way. Or if there is a better way. Maybe also hide chunks that are behind other chunks etc.

I thought your asset is doing this on the GPU?

Thanks!

1 Like

No, what you’re doing is regular frustum culling, it’s already done by Unity. Doing it twice can’t increase FPS :slight_smile:

What I mean is to select 1 camera position and compare FPS with all chunks enabled and some chunks manually disabled in the hierarchy. Not the ones which are outside camera frustum, but the ones which are inside, but can’t be seen. Example: https://i.imgur.com/N0Zmdbb.png

That’s exactly what OC does

Yeah but the outcome is disabled chunks. And you can do it yourself to approximate the potential effect of OC.

1 Like

If I disable my some of my chunks it get’s more performant, yes :slight_smile:

I believe when walking on the surface, a big problem is chunks that are under the “surface ground chunks” which I cannot see anyway but I guess they are all rendered…

Does your asset help with These? Then I guess my performance should be a lot better (for GPU, the other stuff is already good)…

Does your asset work with transparent parts also? In my case like a Ground chunk under a water chunk? Or a large Building but with big windows on all sides?

I would really like to test and give you feedback and when it is helping and not too expensive I will gladly buy it. :slight_smile:

Thanks

1 Like

Then it will help. Especially if you have realtime shadows from the sun, so invisible underground chunks are also rendered into the shadowmap.

It shouldn’t be an issue

2 Likes

Yes I have these! I am using “Enviro” and also additional torch (point) lights etc.

1 Like

Free demo is available!
Requirements: Windows x64, DX11, Unity 2017+
PM me if you’d like to check it out

2 Likes

The demo was updated and now supports ILL2CPP

1 Like

I’d love to check out the demo. I’ll send you a PM

1 Like

By default, it consumes 0.050 ms per frame to scan currently active scenes to detect new objects and process them according to the layer rules you mentioned and other settings.

Also it spends another 0.050 ms to validate active occludees and remove them from the GPU buffers when their gameobjects are removed from the scene.

You can change the time limits or completely disable the first feature if it doesn’t fit your game (there are other ways to manage objects).

The real time consumer is dynamic occludees because their transforms must be checked every frame and all changes must be sent to GPU. It’s expensive and most likely it’s faster to simply draw them, especially for instanced objects. More details in documentation (soon™).

Other than these 3 things, nothing important is done on CPU.

1 Like