Occlusion Culling Now Live in Roblox Client

When will we get support for mobile devices (including the Quest 2), It’ll really benefit playing on VR on the Quest and will make it more playable with higher graphics quality

Will it be possible to disable this? Some games don’t exactly benefit from this, as its likely it takes more resources to do the culling rather than what it’s meant to save.

Thanks for the reply.

The helmet mesh isn’t inverted, but it is pretty small (about 0.5 studs around) and very close to the camera. Could this cause accuracy to be lost? Also, I should probably mention it uses a specialmesh.

This is really helpful to all of us. Thank you!

It doesn’t take that much resources so i don’t see a reason why it would be toggleable.

That shouldn’t be a problem. Do you have a place or a place file you can share that repros this?

It’s more likely to use a mesh with fewer unique vertex positions and fewer polygons. There is a hard cutoff with too many vertices, but that number is subject to change, so I’d rather not say what it’s current value is. Additionally, each vertex or polygon has a cost. The more costly a mesh is, the less likely it is to be used.

Yes, that would be cool if used well! That’s what we call “occlusion hints”. It is something we’ve discussed internally, but I can’t comment on when or even if we’ll ever ship that.

Our goal is for it to automatically tune itself for the current scene on the current device, not just globally for an entire experience. There are many places that have a mix of interiors that benefit a lot from occlusion culling and wide open exteriors that benefit very little. How much it helps and how much it costs also varies across devices and platforms. So, we have auto-tuning that will seamlessly scale back occlusion culling until it doesn’t hurt overall performance, and then scale it back up when it is helping again.

2 Likes

Hi, firstly, thank you for the reply. I understand the point you’re making with this, but I do not think it makes much sense.

For some games, specially indoors ones such as is my case, using a lot of meshes, it is quite critical to have information like this as we need to optimize wherever we can. If the concern here is that the number may change at any moment, you could just update the post or send a notification in this thread (just an example). The point is that it would be far more useful for us to know what the number is, or at least somewhat of a range, than to be in the dark about it.

Meshes can go all the way from very low poly to amounts higher than 10k tris, we need to know.

E.g.: would it be more useful to split a big mesh in multiple lower poly meshes in order to enable occlusion? Should we prefer parts for walls? Etc.

EDIT: After some quick testing, we’ve determined that occlusion will cease to work at close range for meshes around 1538 vertices and higher, and at a 77 studs range, 386 vertices was no longer occluding.

I just found out the helmet issue does not exist outside of VR which indicates it might be apart of the viewport issue.

This place replicates the problem in VR:
VRhelmetculling.rbxl (385.8 KB)

That makes a lot of sense actually. VR uses a central eye position that’s shifted slightly back. The helmet occlusion for this “cyclops” eye will be slightly different from helmet occlusion seen from either eye, which could cause those artefacts.

A fix to VR occlusion is in the pipeline and should roll out at the start of next year.

In the meantime, you can probably work around it by changing the helmet material to be alpha tested. This will make it slightly more expensive, but it should disable it from being used as an occluder without changing the appearance of the helmet. Once the VR fix rolls out, you could remove this ugly hack.

The hard limit is related only to vertex count, after merging away duplicate positions. For example, a cube mesh normally has 24 vertices, because each of the 8 corners has 3 different normals for the 3 faces meeting at that vertex. But occlusion ignores normals and UVs and the like, so occlusion only counts 8 vertices, not 24. I recognize that you can experimentally determine the current limit, so I’ll save you the time and tell you that it is currently about 2000 – but that value is arbitrary, and we reserve the right to raise or lower it at any time!

Even meshes that satisfy the hard limit may not be used if the algorithm decides that considering the mesh isn’t worth the time it takes.

That’s better for occlusion but (probably) worse for the GPU. If you draw all those meshes anyway, it is worse for the GPU. If you can draw some but not others, it may be better for the GPU. You’ll have to decide if splitting meshes is worth it for you. If you do split meshes, I recommend splitting high-poly details from low-poly overall shape, and I recommend splitting “naturally” where clumps of geo reside. It could also make sense to separate things like interiors and exteriors of buildings.

Block parts have special case code that exploits their known mathematical symmetries and the fact that the oriented bounding box is the mesh itself. This makes them about 1/2 the cost of a cube-shaped mesh. So yes, block parts are preferred for occlusion culling.

You can fake hinting by putting blocks (or other meshes) inside walls. This is not awesome, because the GPU will draw those parts! This affects GPU performance, but it may also affect visuals at the edge of the current cull radius, because the “hidden” block may be closer to the camera than one of the meshes that hides it, so you may sometimes see a block that looks hidden in Studio and in most cases in the client. If you do hide blocks inside geo to get their occlusion properties, I recommend doing them such a way that you can easily go back and remove or modify all of them at once. I don’t personally know content creation in Studio well enough to make a more specific suggestion than that.

Yes, we recognize again and again that many devs want the extra control to craft custom occlusion for better performance (aka occlusion hints). But, I can’t say when or even if such a feature will ever come. Don’t hear me saying either “yes we’ll do it” or “no you’ll never get it”! I am just acknowledging that many devs want this without saying anything either way about an unannounced feature.

4 Likes

I don’t feel like this was the best idea, because I am seeing some issues with high fog, and not being able to see some things, im guessing there’s a issue with rendering or part positioning.

(Lots of issues here: Project Lazarus: 💀 ZOMBIES 💀 - Roblox)
On research

Noticing some odd behavior I don’t think was present prior to the update. Updating a part in a ViewportFrame per render step with Size and CFrame (where real change is noticeable, aka not ghost updates) previously didn’t cause any lag, but now it does. MicroProfiler is spamming Part and Instance over and over per frame as if the part is being generated violently over and over. Very odd, perhaps check that out.

1 Like

Is there a reason that disabled highlights prevent something from being culled here? The highlight is disabled, so it’s not making the object visibly rendered in any way.
Potentially similar reasoning to disabled highlights still counting towards the highlight limit?

By live to roblox clients, can this be used in public experiences?

Yep

Will this feature be coming to mobile?

That is fixed in an upcoming release.

Yes, once we are satisfied with its stability across all mobile devices and experiences.

3 Likes

Roblox sure has come a long way. This is massive.

Just found a bug with occlusion culling and SpecialMeshes:

Repro:

  1. Create a SpecialMesh with MeshType=Cylinder.
  2. Set SpecialMesh.Scale to a low value on one of the two axes that control the width of the cylinder. This example is using [1, 1, 0.1]

Occlusion Culling SpecialMesh bug.rbxl (69.9 KB)

3 Likes

We want more updates like this We want innovative features or various helpful tools that help developers

1 Like