I have a strange problem when trying to blend two overlapping surfaces (same depth)

96 Views Asked by At

I have two surfaces.

One as the background (rendered first).

The other as my "canvas" (rendered last).

I found a very strange problem when I tried to use blending to achieve a transparent effect!

Even though I have rendered in the "recommended" rendering order, I still can't get the transparency effect...

enter image description here

I had to use some "tricks" to achieve the effect I wanted.

enter image description here

My compromise now is either to use glDepthFunc(GL_LEQUAL) or to adjust the Z of the second surface a little(plus 0.001f)...

glDepthFunc(GL_LEQUAL);
quad.Draw();//the background    
glDepthFunc(GL_LESS);

or

std::vector<GLfloat> Vtx = {
         1.0f,  1.0f, 0.0f,  // top right
         1.0f, -1.0f, 0.0f,  // bottom right
        -1.0f, -1.0f, 0.0f,  // bottom left
        -1.0f,  1.0f, 0.0f   // top left 
    };
std::vector<GLfloat> Vtx2 = {
         1.0f,  1.0f, 0.001f,  // top right
         1.0f, -1.0f, 0.001f,  // bottom right
        -1.0f, -1.0f, 0.001f,  // bottom left
        -1.0f,  1.0f, 0.001f   // top left 
    };

I'd like to know why this is happening. Doesn't it follow the correct rendering order to correctly blend each object?

Is there a better way to achieve a transparent effect on those two surfaces?

1

There are 1 best solutions below

0
potter john On

I realized that this is actually a very complicated issue...

First of all, you have to put glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) in the right place.

And I put it in the wrong place at the beginning (I even put glClear(GL_COLOR_BUFFER_BIT) and glClear(GL_DEPTH_BUFFER_BIT) in two different places), which led to the chaos of all the results later!

And then about the Z-axis of NDC... Yes, the -z of NDC's Z-axis is pointing to my eyes, and only after the whole scene becomes 3D is +z pointing to my eyes...

After using a normal projection matrix

enter image description here

But there is another problem... if I really overlap the two planes ( both z's are 0) there will be z-fighting (at least in the 3D scene)

enter image description here

The following picture shows the 2D scene without glDepthFunc(GL_LEQUAL) (also the two surfaces are completely overlapped)

enter image description here

My current solution is:

Add glDepthFunc(GL_LEQUAL) directly to the code in the 2D scene (yes, I don't know why, but z-fighting disappears when there is no projection matrix)...

Or add -0.001f to all z-coordinates (glClear must be placed in the right place)

std::vector<GLfloat> Vtx2 = {
     1.0f, 1.0f, -0.001f, // top right
     1.0f, -1.0f, -0.001f, // bottom right
    -1.0f, -1.0f, -0.001f, // bottom left
    -1.0f, 1.0f, -0.001f // top left 
}.