4

I want to render a big scene(a modeled city) using WebGL, and I think occlusion culling is a good way to optimize the performance.

And I know WebGL 2.0 has a new feature called 'Query Objects' to get the occlusion information. But every time I use gl.getQueryParameter(query, gl.QUERY_RESULT), I got the same result 1.

And I wrote a demo here to explain the problem:

    var query = gl.createQuery();
    gl.beginQuery(gl.ANY_SAMPLES_PASSED, query);
    gl.drawArrays(gl.TRIANGLES,0,n);
    gl.endQuery(gl.ANY_SAMPLES_PASSED);

    var tick = function(){
        if(!gl.getQueryParameter(query,gl.QUERY_RESULT_AVAILABLE)){
            requestAnimationFrame(tick);
            return;
        }
        var result = gl.getQueryParameter(query,gl.QUERY_RESULT);
        console.log(Number(result));
        gl.deleteQuery(query);
    };

    tick();

and here are my vertex information that the sceond triangle is obscured by the first triangle.

    var vertexData = new Float32Array([
            0.0,0.5,0.0,        //first triangle
            -0.5,-0.5,0.0,
            0.5,-0.5,0.0,

            0.0,0.5,-0.5,       //second triangle
            -0.5,-0.5,-0.5,
            0.5,-0.5,-0.5
    ]);

and the result is always 1.

What's the result '1' stands for?

In addition, how could I do occlusion culling using WebGL 2.0? Is there any helpful samples?

HT XU
  • 137
  • 1
  • 3
  • 8
  • So you have *one* draw call drawing *two* triangles where one is covered by the other, and ask for `ANY_SAMPLES_PASSED` which gives you [`1` resembling `true`](https://www.khronos.org/opengles/sdk/docs/man3/html/glBeginQuery.xhtml) as all your first triangle samples passed which easily satisfies "any sample". – LJᛃ Oct 17 '16 at 14:40

3 Answers3

4

Occlusion queries and occlusion culling are NOT the same thing.

Basic object culling can be (and should be) done entirely on the CPU (e.g. frustum checks on object bounding boxes, portal visibility, octrees, etc) far more effectively than on the GPU because the application can exploit scene level knowledge the graphics driver simply doesn't have.

On the GPU occlusion culling is most easily provided by rendering opaque objects using a front-to-back render order (again, game engine will usually crudely sort object batches), and using the depth test to cull obscured things.

Occlusion queries are a very specialized tool that are useful for a small number of visual effects (e.g. lens flare), but far too difficult to pipeline for any aggressive culling within a single frame.

solidpixel
  • 10,688
  • 1
  • 20
  • 33
  • 1
    To add to isogen74's answer on top to CPU based culling using a well designed data structure for your PVS (potentially visible set) is a must for large scenes. As a simple example split the world into 1x1km areas and decide you can only see 5km away. Then use the frustum to figure out which 1x1k chunks are actually in view. Only try to draw those things. That's just one simple example. There are infinite ways to design PVSes. Portals is another for indoor scenes. – gman Oct 18 '16 at 13:08
3

First of all, here is a good example of how to use the WebGL 2 occlusion query API.

Contrary to the other answers, occlusion queries can absolutely be used to implement occlusion culling. The catch is that you're going to need the help of somewhat complex CPU side data structures/algorithms to help you. Instead of explaining it myself here poorly, I defer you to the actual experts GPU Gems 2 - Chapter 6 Hardware Occlusion Queries Made Useful. Without proper algorithms, your occlusion query itself will be more expensive than just rendering the object!

1

gl.ANY_SAMPLES_PASSED results just in true (1) or false (0). It is not the information how many samples passed, instead ist gives you the result of true (1) that any sample passed, does not matter which one.