尝试混合两个重叠表面(相同深度)时我遇到了一个奇怪的问题

问题描述 投票:0回答:1

我有两个表面。

一个作为背景(先渲染)。

另一个作为我的“画布”(最后渲染)。

我在尝试使用混合来实现透明效果的时候发现了一个很奇怪的问题!

虽然我按照“推荐”的渲染顺序渲染了,还是出不了透明效果……

我不得不使用一些“技巧”来达到我想要的效果。

我现在的妥协是要么使用

glDepthFunc(GL_LEQUAL)
,要么稍微调整第二个表面的Z(加上
0.001f
)...

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

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

我想知道为什么会这样。它不是遵循正确的渲染顺序来正确混合每个对象吗?

有没有更好的方法可以在这两个表面上实现透明效果?

c++ opengl blending depth-testing
1个回答
-1
投票

我意识到这其实是一个很复杂的问题...

首先,你必须把

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
放在正确的位置。

而且我一开始放错了地方(我什至把

glClear(GL_COLOR_BUFFER_BIT)
glClear(GL_DEPTH_BUFFER_BIT)
放在了两个不同的地方),导致后面所有的结果都乱了!

然后关于NDC的Z轴... 是的,NDC的Z轴的-z是指向我的眼睛,只有整个场景变成3D后+z才指向我的眼睛...

使用普通投影矩阵后

但是还有一个问题……如果我真的把两个平面重叠了(两个z都是0) 会有z-fighting(至少在3D场景中)

下图是没有

glDepthFunc(GL_LEQUAL)
的2D场景(也是两个面完全重叠)

我目前的解决方案是:

直接在2D场景中的代码中添加

glDepthFunc(GL_LEQUAL)
(是的,我不知道为什么,但是在没有投影矩阵的情况下z-fighting就消失了)...

或者在所有z坐标上加上

-0.001f
glClear
一定要放对地方)

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 
}.
© www.soinside.com 2019 - 2024. All rights reserved.