【发布时间】:2012-09-20 13:03:17
【问题描述】:
我需要将球体渲染到纹理(使用帧缓冲区对象 (FBO) 完成),然后将该纹理与后台缓冲区进行 alpha 混合。到目前为止,我没有对纹理进行任何处理,除了在每一帧开始时清除它。
我应该说我的场景只包含一个空旷空间中的行星,球体应该出现在行星旁边或周围(现在有点像月亮)。当我将球体直接渲染到后台缓冲区时,它会正确显示;但是当我执行将其渲染为纹理然后将该纹理与后台缓冲区混合的中间步骤时,球体仅在它位于行星前面时才会出现,不在前面的部分只是“切断” ":
我使用glutSolidSphere 将球体渲染为绑定到 FBO 的 RGBA8 全屏纹理,确保每个球体像素接收 1.0 的 alpha 值。然后,我将纹理传递给片段着色器程序,并使用此代码在 alpha 混合时将全屏四边形(纹理映射到其上)渲染到后缓冲区:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2i(0, 1);
glVertex3i(-1, 1, -1); // TOP LEFT
glTexCoord2i(0, 0);
glVertex3i(-1, -1, -1); // BOTTOM LEFT
glTexCoord2i(1, 0);
glVertex3i( 1, -1, -1); // BOTTOM RIGHT
glTexCoord2i(1, 1);
glVertex3i( 1, 1, -1); // TOP RIGHT
glEnd();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
这是着色器代码(取自用 Cg 编写的 FX 文件):
sampler2D BlitSamp = sampler_state
{
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};
float4 blendPS(float2 texcoords : TEXCOORD0) : COLOR
{
float4 outColor = tex2D(BlitSamp, texcoords);
return outColor;
}
我什至不知道这是深度缓冲区的问题还是 alpha 混合的问题,我尝试了很多启用和禁用深度测试(将深度缓冲区附加到 FBO)和 alpha 混合的组合.
编辑:我尝试将一个空白的全屏四边形直接渲染到后台缓冲区,甚至在地球边缘裁剪。出于某种原因,启用渲染四边形的深度测试(即删除线 glDisable(GL_DEPTH_TEST) 和 glEnable(GL_DEPTH_TEST) in the code above)解决了这个问题,但是现在除了行星和球体之外的所有东西都显示为白色:
我确定(并且可以确认)纹理的 Alpha 通道在每个像素上都是 0,但球体除外,所以我不明白可以在哪里引入白度。 (也仍然有兴趣解释为什么启用深度测试会产生这种效果。)
【问题讨论】:
-
您是否启用了 alpha 测试 (
GL_ALPHA_TEST)? -
你能生成一个显示问题的最小编译示例吗?
-
您的着色器代码在我看来不像 GLSL。你用的是 Cg 还是类似的东西?
-
是CG,不好意思,忘记说了。我应该禁用 GL_ALPHA_TEST,对吗?我会尽快检查。
-
是的,它应该被禁用。其他要检查的事项: 1. 将shader的body改成
return float4(1, 1, 1, texcoords.x);有什么效果? (语法可能关闭,有一段时间没有接触 Cg) 2. 当您将四边形偏离中心放置时会发生什么,例如向左移动一个单位?
标签: c++ opengl shader alphablending render-to-texture