Occlusion Query - No performance improvement?

I’ve been trying out the Occlusion Query feature but I see absolutely zero FPS increase…

You can try in this example with a super high dense sphere:

Enabling or disabling the occlusion plane, does nothing to the FPS nor the Draw Call.
Only the Active indices number spikes up and down, but the FPS stays the same…? Or am I missing something?


I’m not moving the camera, just ON and OFF the meshes from the Inspector.
But if I turn off the sphere, which is behind the occluded plane, the FPS increases dramatically.
I don’t understand.

It is mostly helping in VR, @RaananW might help to confirm ?

You must move the camera: when the sphere is completely behind the plane, the screen will turn green as the sphere is occluded and it won’t be rendered. You will see a huge improvement in the GPU time (on my computer, it’s around 0.5ms when the sphere is occluded and ~6ms when it is not).

Yes, the BG colours change accordingly, no prob there.

Is just that FPS wise, stays the exact same, regardless of moving the camera. I tried it on 3 laptops with different specs. 6fps, 30fps, 40fps. No FPS gain whatsoever…
Which makes me wonder what’s the point. Do I have to isVisible manually if isOccluded returns true? Am I missing something?

If the fps is not limited by the GPU then you won’t get any gain with occlusion queries. As the GPU is doing processing in parallel to the CPU and the base fps is 60, if the GPU takes less than 16.6ms (=1000ms/60fps) to render things, the fps will remain at 60fps, assuming the CPU itself does not take more than 16.6ms to do its processing. If the CPU is the bottleneck, the GPU has even more times available before becoming the bottleneck itself.


Ok, I understood now. Thanks for the explanations, it should be added in the docs or something.

But what do you think of this idea?

I’m making two spheres, one low poly for occlusion calculations, and another high poly for visibility. And enabling disabling it based on the isOccluded return.

Is this idea too gimmicky and costly for many meshes at once? Because it completely freezes from time to time.

I have a series of rooms with high poly meshes and trying to find some solutions.
I’ve tried the LODding feature, but the filesize keeps on increasing having many extra lod meshes.

There’s no point to create a second sphere, as the occlusion query is working by rendering the bounding box of the mesh that is queried (so it is even faster than rendering a low poly sphere) and looking if at least a pixel of this box is visible. If not, the queried mesh is not displayed.

Something which is important, however, is to make sure the objects you query are drawn late, to increase the likelihood that some other objects drawn earlier will cover them. One way to do that is to create those objects last, as by default the rendering order of the meshes is the creation order. You could also try to sort the meshes from front to back each frame.


Hmm, but if I don’t create a second sphere, the bounding box goes away with the mesh, and never shows back. Or you mean something else?


You should not modify the isVisible property: the mesh will be automatically displayed/not displayed based on the outcome of the occlusion query. See the first PG you linked:


When the mesh is hidden you will see:

And when it is visible:


But I’m going back to the same problem… Which is I can’t see any significant FPS increase…

In the gimmick solution of completely disabling it with isVisible I hit 60fps everytime the sphere is occluded, much more than relying on occlusion query alone:

I’m just wondering if it’s a “good” approach or if you have any other idea to improve it…

I don’t understand how you can have better fps in your PG when the code to handle “sphere” is the same: you only hide “sphere2” based on “sphere” visibility. It won’t change anything regarding “sphere”. Do you have the same figures than me in the inspector / Stats pane depending on the sphere occlusion? If yes then everything is working as expected. If you don’t see any difference in fps, it means you are not GPU bound (I don’t see any difference on my computer, I’m always at 60fps).

I noticed that even when the sphere is occluded, it is sometimes drawn (when the query needs more than one frame to resolve). This PR will help with that:

1 Like


Not at all… when I use just the Occlusion Query alone the Active Indice in Inspector stats is spiking up and down.

I’ve made two recordings, one with default Occlusion Query, another with the isVisible gimmick:

https://playground.babylonjs.com/#QDAZ80#133 :

https://playground.babylonjs.com/#QDAZ80#134 :

The isVisible dramatically improves the FPS to 60 or more, whilst the default Occlusion Query barely improves 3 FPS, on green/occluded state.

I think my PR should fix your problem. It seems the occlusion queries always take more than one frame to complete on your computer, so the occlusion check always returned “false” which means “display the mesh”.

1 Like