-2

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?

genpfault
  • 51,148
  • 11
  • 85
  • 139
  • Which is the background and which is the canvas? The waves are in the background? – Neil Apr 19 '23 at 03:39
  • 1
    Yes, the wave is the background (the first call to quad.Draw()), the The color gradient is the second call to quad.Draw(). – potter john Apr 19 '23 at 03:44
  • Do you use a projection matrix? If yes, the Z axis points out of the view. If not, in NDC the z axis points in the view. – Rabbid76 Apr 19 '23 at 04:42
  • No, I don't use the projection matrix for now (I only need a full-screen quad for now), it shouldn't have much to do with the projection matrix (I remember that the z-axis is always -z towards the far side and +z towards my eyes, and it seems to be the same after projection)... – potter john Apr 19 '23 at 04:55
  • 1
    *"I remember that the z-axis is always -z towards the far side and +z towards my eyes"* - NO! With NDC (Normalized Device Coordinates) it is the other way around. If you don't use a projection matrix the z axis points in the view. The projection matrix mirrors the Z axis and turns a right handed system into a left handed sytem. – Rabbid76 Apr 19 '23 at 04:59
  • Anyway, you have to draw the background first without depth test. After that draw the scene with enabled blending. – Rabbid76 Apr 19 '23 at 05:03
  • OMG, YOU ARE RIGHT!!!!!!!!!!! NDC's -z is pointing to my eye!!!!!!!!!!!! – potter john Apr 19 '23 at 10:12

1 Answers1

-2

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 
}.