【发布时间】:2015-02-28 19:23:11
【问题描述】:
我有一个包含透明和不透明 2d 项目的场景。我首先以从前到后的顺序渲染启用了深度测试和深度掩码(写入)的不透明项目。然后我将深度蒙版设置为 false(不禁用深度测试),启用混合并从后到前渲染透明的。
但问题是透明项目没有正确绘制。当我为它们使用 glDepthFunc(GL_LESS) 时,它们根本不会被绘制,而当我使用 glDepthFunc(GL_EQUAL) 时,它们会被绘制,但应该被不透明项目遮挡的那些则不会。它们只是在所有内容之上渲染。
渲染例程中的代码如下所示:
// Set the clear color
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepthf(1.f);
glDepthRangef(0.f, 1.f);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
// Draw opaque items
glDepthFunc(GL_LESS);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderOpaque();
// Draw transparent items
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
renderAlpha();
glDisable(GL_BLEND);
项目的 z 值按以下方式设置:
// Bottom layer (background) is 0 and then layer is incremented
// by one for each view that sits on top
// I use the far value (something like 10000.f) to divide to get
// something between 0.0 and 1.0 (from back to front: 0.0/10k, 1.0/10k,
// 2.0/10k etc)
float zTranslation = static_cast<float>(GetLayer()) /
TheCamera::Instance().GetFar();
glm::mat4 model = glm::translate(glm::mat4(1.f),
glm::vec3(m_absoluteFrame.origin.x,
m_absoluteFrame.origin.y,
zTranslation));
glm::mat4 MVP = muiKit::TheCamera::Instance().GetProjection() *
muiKit::TheCamera::Instance().GetView() *
model;
然后将MVP矩阵传递给着色器以设置gl_Position...
gl_Position = MVP * vec4(imageVertex.xyz, 1);
而且我还传递纹理坐标和索引等,并使用 glDrawElements 批量绘制。
我在这里做错了什么?
另外,即使我是新手,我也觉得当我渲染透明项目时深度函数应该是 GL_GREATER ......不是吗?不知何故,知道我将它们呈现在从后到前的顺序对我来说是有意义的。
【问题讨论】:
-
愚蠢的问题,可能是:您确定您的目标附加了深度缓冲区吗?
-
嗯...根本不转储。我在想这个。我需要在 GLES2 中自己创建一个深度缓冲区吗?我还没有创建一个原因,我认为默认的 FBO 也带有深度缓冲区。另一方面,为什么我不透明的从前到后的东西会起作用?如果没有深度缓冲区,它们不应该一个一个地绘制吗?
-
@Tommy 我已经阅读了一些内容,显然默认帧缓冲区不需要额外的附件。 iOS 是一个例外,您必须附加自己的渲染和深度缓冲区,但在 C++/Linux 中则不然。此外,我在 EGL 配置中正确设置了 DEPTH 位,所以这不是问题。