我已经在opengl工作了一段时间相对顺利,但最近我注意到当我将带有透明纹理的图元渲染到我的fbo纹理(自定义帧缓冲区)时,它使fbo纹理在像素处透明基元的纹理是透明的。问题是这个原始(纯色)背后的东西已经在透明之前渲染了。因此,fbo纹理在这些像素处不应该是透明的 - 混合固体和放大器。透明的颜色应该会产生纯色,不应该吗?
所以基本上,opengl正在为我的fbo纹理添加透明度,因为最后绘制的基元具有透明像素,即使其背后的纯色已经被绘制到fbo纹理中。不应该将透明纹理与fbo的现有像素进行opengl混合,如果在渲染透明图元之前fbo纹理已经用纯色填充,会产生纯色吗?
当我将fbo纹理渲染到默认帧缓冲区时会发生什么,清晰的颜色会渗透到部分区域 - 最后绘制的纹理是透明的。但是当我将相同的场景直接渲染到默认的opengl帧缓冲区时,场景看起来很好,并且清晰的颜色不会渗透到透明纹理中。
更有趣的是glClearColor - 颜色仅在原始纹理的alpha具有渐变的情况下可见 - 清晰的颜色对纹理alpha为1.0或0.0的位置没有影响...这是一个错误吗?它似乎以0.5 alpha的像素影响原始纹理。然后进一步向上或向下移动会降低glClearColor的影响。
我知道这是一个复杂的问题/情况,老实说我尽力解释
我正在使用:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
将部分透明的基元绘制到fbo纹理中,然后将fbo纹理绘制到默认的帧缓冲区
这是绘制到默认opengl fbo中的fbo纹理:
glClearColor设置为红色。
答案 0 :(得分:1)
混合固体和透明的颜色应该会产生纯色,不应该吗?
仅当您的混合模式告诉它时。它没有:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
这将对颜色的所有四个组件应用相同的混合操作。这会导致最终的alpha值是源alpha自身相乘的结果,并将其添加到目标alpha时间1-src alpha。
现在,您可以为颜色和alpha使用单独的混合函数:
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
最后两个参数仅指定alpha的混合,而前两个参数指定RGB颜色的混合。所以这保留了alpha。 GL 3.x及更高版本提供单独的混合功能,但也可作为旧硬件的扩展。
但在我看来,你可能根本不想改变阿尔法。所以在渲染到纹理时只需mask alpha writes:
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
当你想再次写入时,不要忘记撤消alpha掩码。