I have a very large scene to render (approx > 10-20M polygons) , using three.js , with an acceptable framerate.
So I am implementing some basic occlusion culling using a WebGL2 renderer .
and here's my problem :
I want to squeeze every performances I can from three.js.
In this scene , there are hundreds of thousands of different individual meshes .
Every mesh has to compute it's own bounding box... that means hundreds of thousands of B-Boxes ...
And I don't think that issuing hundreds of thousands visibility queries would be very fast.
So is it possible to merge all these bounding boxes , send only one visibility query draw call , and somehow retrieve every bounding box and it's own visibility query result?
Asked
Active
Viewed 161 times
0

gman
- 100,619
- 31
- 269
- 393

Amine Bensalem
- 362
- 3
- 15
-
I'm a little confused. Are you computing the bounding boxes every time you want to calculate occlusion? Calculating a geometry's bounding box should be one-and-done. Do it once when you first create the geometry, and it won't change (unless you change the geometry). You could even create a second bounding box stored in the mesh which bakes-in the mesh's transformation. You only need to "re-bake" the mesh's bounding box when its transformation matrix changes. – TheJim01 Aug 10 '17 at 14:37
-
hello @TheJim01 , I am not re-computing the bboxes while rendering ... I do it only once ... The problem here is not computing the boxes ... it's rather a visibility query for every box. And to make a visibility query , you have to send a draw call for every box. And I am wondering if we could send all these boxes in a single draw call , instead of querying visibility for each box. – Amine Bensalem Aug 10 '17 at 14:51
-
Sounds expensive no matter what you do. Could some (admittedly hacky) ray-casting help? Fire a ray form each corner of your boxes toward the camera. If they all intersect another box, the mesh is occluded. I honestly don't know if that will be better or worse for you. Have you considered doing size culling instead? I've sent lists of bounding spheres and the camera position into a webworker, and it spits out which ones are too small to care about anymore. It's async, but better than nothing. – TheJim01 Aug 10 '17 at 14:59
-
I actually gave a thought to this raycasting method like 1 week ago, but it will not work. think about it , if your object's 4 corners are occluded by 4 different meshes , but not the center , it will be invisible even though it shouldn't. I am trying another way... I am going to give to each box a unique vertex RGB color ID I will then batch the whole bounding boxes scene together I will then render the scene in a texture and then apply either some mip mapping algorithm or just retrieve that texture's mipmap and then I will fetch which colors has been recorded on the texture – Amine Bensalem Aug 10 '17 at 15:24
-
That approach is similar to [GPU picking](https://threejs.org/examples/webgl_interactive_cubes_gpu.html). I was going to suggest something similar, but thought the extra render + processing might be as expensive as anything else. – TheJim01 Aug 10 '17 at 15:46
-
You should consider using the instanced drawingto reduce draw calls! Upload transformations into `WebGLBuffer`, bind Mesh, draw all instances in one call using `drawArraysInstanced` or `drawElementsInstanced`. If the boxes move you need to remember the index of the transformation in the buffer and update it with `bufferSubData`. Alternatively you can setup a `WebWorker` which will calculate the visibility of the boxes to reduce the bottleneck on the main thread. For beter performance you can also consider using bounding spheres since they are cheaper to test. – Bellian Aug 11 '17 at 14:54