Question

I am working on a augmented reality application and need to sort the rendering of three different kinds of geometry.

Level 1
Background geometry. This is a set of triangles that represent basic architecture. Walls etc.

Level 2
Photograph plane. A photograph of the architecture placed as a texture on a plane in space. That plane is geometrically in front of Level 1 (as seen from the virtual camera)

Level 3
Dynamic geometry. These are primitives like boxes etc, to augment the scene. They are geometrically behind Level 2, because they are correctly placed inside the coordinate system of Level 1

Desired effect:
a) I want Level_2 to always be drawn in front of Level_1 This is automatically achieved by placing the image plane closer to the camera.

b) I want Level_3 to be occluded correctly against Level_1, thereby hiding parts of a dynamic box, if it is placed partly behind a wall of Level_1. This automatically happens with normal pipeline too. Depth testing etc.

c) I want all Fragments/Pixels of Level_3 to be drawn ABOVE Level_2, even if they are actually behind it. The effect should make the objects appear, as if they are occluded by parts of the photograph.

I know that this is possible, because i have an application in X3Dom (which renders to webgl) that can achieve this effect via the "sortkey" attribute. But i could not recreate the same effect in pure OpenGL. I thought it should be a simple use of Stencilbuffer or Z-Buffer tricks, but i don't get it to work. How do i give an "always pass" to the Level_3 geometry, so that it is drawn above everything else, but also correctly occluded against Level_1? Or how do i make Level_2 hide only Level_1 and not Level_3 even if it is in front of both?

Basically:
1) Level_2 hides Level_1
2) Level_1 and Level_3 occlude each other
3) Visible parts of Level_3 (against Level_1) are not occluded by Level_2

Any help?

Thanks!

Was it helpful?

Solution 2

Found out after a while, but forgot to update here. The solution was as simple as expected. DepthTesting stays active all the time. Rendering is called in order 1, 2, 3. Rendering of level 2 is enclosed in

gl.glDepthMask(false);

gl.glDepthMask(true);

Allows for correct depth rendering and occlusion of every level but will not change the depth buffer from rendering level 2 elements. Therefore level 3 elements ignore the depth of level 2 and clip against level 1.

OTHER TIPS

You need to render scene in three stages accordingly to levels you've described. The level_1 should be rendered first with depth test enabled. Then, you should render level_2 with disabled depth test. And at third stage you should render level_3 with depth test enabled. Thus the geometry of level_2 would be rendered totally overlapping level_2 meanwhile it would not effect z-buffer, so the geometry of level_3 would be rendered as if level_2 wasn't be rendered at all.

To enable and disable depth test you should call glEnable and glDisable functions. Calling glDisable(GL_DEPTH_TEST) would disable depth test and update of depth buffer. To enable depth test and writing to depth buffer you should call glEnable(GL_DEPTH_TEST)

General steps you need to do:

    /*
    Render level_1 
    */

    glDisable(GL_DEPTH_TEST); //disable depth test and update of the depth buffer

    /*
    Render level_2         
    */

    glEnable(GL_DEPTH_TEST);  //enable depth test and update of the depth buffer

    /*
    Render level_3         
    */
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top