Author Topic: Object Occlusion Culling?  (Read 1666 times)

sweatyc

  • Newbie
  • *
  • Posts: 7
    • View Profile
Object Occlusion Culling?
« on: November 28, 2018, 05:41:04 AM »
It's me again  :)

I would like to know if VoxelPlay supports occlusion culling for object (static or moving), with Unity default one or having its own one?

2 solutions I can think of:

A: Just like Unity's occlusion culling (preferred)
- spawned object will be hidden when player move far away enough, behind the player, or blocked by walls, lands, etc.
- (I don't think I can get Unity's default one works with VoxelPlay, coz it requires pre-bake etc.)
- (A dynamic occlusion culling plugin like this may works? Please confirm.)

B: Cull with underneath chuck
- spawned object will reference to it's underneath chunk.
- if the object is moving, it keep checking its underneath chunk.
- when the underneath chunk gets hidden by Voxelplay for excess chunks pool, the object gets hidden too.


A example can be the deer in the demo scene, I have an AI script on it so it randomly moving (can be performance heavy) and spawning a lot of it all over the map. Occlusion culling is needed so only the ones player sees is showing. Or, at least they should be hidden together with the land.



My deers :D

Chunk got hidden but not the deers, they will fall to hell soon...  :-[
« Last Edit: November 28, 2018, 06:05:54 AM by sweatyc »

JSwigart

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: Object Occlusion Culling?
« Reply #1 on: November 28, 2018, 03:10:39 PM »
I'm not sure whether VoxelPlay uses something more than frustrum culling, but if there is interest to do more, this is a good resource https://tomcc.github.io/2014/08/31/visibility-2.html

It's a good easy to use algorithm for getting better culling out of a voxel engine, particularly if it involves caves and lots of vertical chunks. It involves maintaining a bit of occlusion data at the chunk level that represents whether looking into one side of the chunk has the potential to see through to another, and then using that data to direct a breadth first search out. In our implementation I did a flood fill from the open voxels along each face of the chunk, to the open voxels along each other face(in a single fill pass). With that information, the breadth first search you use for finding visible chunks can use that metadata for eliminating a huge number of chunks from the render list. A word of warning though, our implementation was pretty expensive on the CPU(the search part, not maintaining the chunk visibility mask), so I would plan from the start to run this on a job. Between using an older version of unity and the mechanism we used for threading, that was difficult for us, so we ended up running the culling in a coroutine to amortize the cost. We also removed the frustrum part of the check so that running it over time was not view dependent.

The other thing we did that VoxelPlay already seems to handle better, is that we did all the chunk baking on the CPU side(in threads but still, no geometry shaders, etc), and the way we show/hid the occluded chunks was by turning off renderers. This was a poor approach, but our game predates geometry shader support and I think a good chunk of the Graphics api. If we could do it again, all the chunk rendering would be performed with Graphics.DrawMesh* I think calls so that the visible set need only be excluded from those batches, and not involve costly enable/disable operations on game objects or components. Also, if you structure your rendering right, the fact that a chunk may be occluded, via cave culling or whatever, would also allow you to avoid rendering any static objects that are children of that chunk as well, without necessarily having to cull those objects individually, though I suppose that is slightly more complicated by the fact that VP supports large footprint multi-blocks, so worst case there may need to be a more involved culling step with those kinds of blocks so that they can render if any chunks their bounds overlaps is visible.

I've long thought that if we were to do it again, I would probably try a job based cave culling approach, and with the resulting visible chunks of that I would manually build a list of data suitable for manually calling Graphics.DrawMesh. Given the nested nature of most static objects under chunks, It should be a more favorable approach to building the visible set than letting unity do a bunch of culling itself without that hierarchial context. This job would also handle the possibility that voxel placeholder meshes may overlap multiple chunks, and properly add them to the render list if any of the chunks it overlaps are visible. I think to fully go this route would be to eliminate MeshRenderers from your chunk game objects, or you would need to do the renderer enable/disable thing as well, though perhaps they could always be disabled and you could just use them as storage for the mesh/materials you would explicitly build a list out of. From the job perspective, the cave culling search itself probably would have to be 1 job, while the jobs to build the renderer lists could perhaps go wider if necessary.

Kronnect

  • Administrator
  • Hero Member
  • *****
  • Posts: 6642
    • View Profile
Re: Object Occlusion Culling?
« Reply #2 on: November 28, 2018, 09:09:49 PM »
Problem with real-time occlusion culling is that it's not guaranteed to provide an overall performance improvement - it really needs to be super-fast to compensate the reduction of ms dedicated to transfer data to the GPU... (also the GPU culling is quite fast so..)
I did some tests with Jobs and found that are not that so fast if you need to ping/pong lot of mesh data to the job structures every frame unless what you're doing in the job is somewhat expensive. This can work if you can afford spanning the work for several frames though.

In any case this is a very interesting field so I'll keep an eye and think about it.

Regarding the chunks pool being exhausted and notifying other objects, I'll check the current options and/or provide support for that. Moving this to Feature Requests!

sweatyc

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Object Occlusion Culling?
« Reply #3 on: November 29, 2018, 03:03:07 AM »
I'm not sure whether VoxelPlay uses something more than frustrum culling, but if there is interest to do more, this is a good resource https://tomcc.github.io/2014/08/31/visibility-2.html
...

Although I don't understand 90% what you've said, thanks for the reply anyway. I assume Kronnect know what you've said.

I think the blog post you provided is about the chunk occlusion culling but not the (moving) object occlusion culling.

Problem with real-time occlusion culling is that it's not guaranteed to provide an overall performance improvement - it really needs to be super-fast to compensate the reduction of ms dedicated to transfer data to the GPU... (also the GPU culling is quite fast so..)
I did some tests with Jobs and found that are not that so fast if you need to ping/pong lot of mesh data to the job structures every frame unless what you're doing in the job is somewhat expensive. This can work if you can afford spanning the work for several frames though.
...

If real-time occlusion culling is not easily possible, chunk pooling to disable objects will satisfy us too.

I wonder how Mincraft do, did they hide the running wild animals and props when player go away too far too?

JSwigart

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: Object Occlusion Culling?
« Reply #4 on: November 29, 2018, 03:21:13 PM »
You are correct seatyc. The cave culling algorithm is about significantly reducing the number of chunks that need rendered, and depending on whether associate static and/or dynamic objects with chunk visibility, can greatly simplify that. This is apparently the technique they used to get Minecraft Pocket edition to acceptable performance levels, where I'm guessing the GPUs aren't quite as up to the task of brute forcing it.

For dynamic entities I think default culling is just fine in most cases. There doesn't tend to be enough of them to cause issues.

Kronnect, VP is already way beyond our implementation in this domain, but the cave culling algorithm cuts the number of chunks that even need to be built(for potential visibility) by huge margins. I assume it will become more favorable the more detailed(and costly) chunks get to build through future potential added features(new voxel shapes, a game using a lot of gameobject based voxel placeholder instances, etc. Hopefully stuff like that can be alleviated through other means, such as the instanced rendering taking responsibility for rendering the geometry of potentially many instances of a voxel placeholder. I don't know enough about geometry shaders to say that new shape types should be pluggable into the geometry shader pipeline without much cost, compared to what we did, which is CPU side jobs to build the chunk geometry.

Kronnect

  • Administrator
  • Hero Member
  • *****
  • Posts: 6642
    • View Profile
Re: Object Occlusion Culling?
« Reply #5 on: November 29, 2018, 04:41:43 PM »
Agreed. Yeah, I'll consider it.