编辑+更好的解决方案:
如果有人遇到我遇到的问题,有两个解决方案。一个是接受的解决方案,但这仅适用于您正在做的事情 。让我解释一下我在做什么:
1。)将星空背景渲染到屏幕
2。)渲染船只,然后将粒子渲染到FBO
3。)将FBO渲染到屏幕
这个问题,以及解决这个问题的方法,首先发生了,因为我正在将FBO与星空背景混合。
真正的解决方案,据说也稍微快一点,就是简单地将星空背景渲染到FBO,然后将FBO渲染到禁用混合的屏幕。使用这种方法,我不需要搞乱glBlendFuncSeparate ......
1。)渲染星星,然后发射,然后渲染粒子到FBO
2。)将FBO渲染到屏幕,禁用混合
----------原始问题:----------
根据我对这个问题的理解,混合被忽略了。具有Alpha透明度的粒子纹理完全覆盖在像素下方。
我正在创建一个自上而下的游戏。相机略微倾斜,以便有一些深度感。我正在渲染我的船只,然后将粒子撕裂在它们上面......
开始OpenGL上下文后
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glCullFace(GL_BACK);
在渲染循环中,我这样做:
glBindFramebuffer(GL_FRAMEBUFFER,ook->fbo);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
entitymgr_render(ook); //Render entities. Always 1.0 alpha textures.
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
//glBlendFunc(GL_SRC_ALPHA,GL_ONE); //This would enable additive blending for non-premult
particlemgr_render(ook); //Render particles. Likely always <1.0 alpha textures
//glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glBindFramebuffer(GL_FRAMEBUFFER,0);
如果我使用上面的代码运行,我会得到这样的结果......
粒子tex:
OGL Profiler(Mac工具)的屏幕截图:
没有渲染任何粒子的FBO的屏幕截图:
FBO的屏幕截图,其中一些粒子呈现在顶部:
正如您所看到的,尽管具有Alpha透明度,但粒子不会与下面呈现的船舶混合。相反,它只是完全覆盖了像素。
最后的注释,在着色器中设置像素透明度正确混合 - 船出现在下方。这是我的着色器:
#version 150
uniform sampler2D s_tex1;
uniform float v4_color;
in vec4 vertex;
in vec3 normal;
in vec2 texcoord;
out vec4 frag_color;
void main()
{
frag_color=texture(s_tex1,texcoord)*v4_color;
if(frag_color.a==0.0) discard;
}
如果我能提供任何内容,请告诉我。
答案 0 :(得分:6)
在我看来,它正在将alpha通道渲染到帧缓冲区中,所以当你编写粒子时,src alpha通道会与目标alpha通道混合,这不是你想要的。
这正是创建glblendfuncseparate()函数的原因。试试这个......
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
因此,粒子的alpha通道将用于确定最终像素的颜色,但源和目标的Alpha通道将一起添加。
答案 1 :(得分:4)
我的猜测是FBO的rgb通道正在被正确渲染,但是因为它也有一个alpha通道,并且它是在启用混合的情况下绘制的,所以最终结果的透明度不正确,其中粒子与太空船重叠。
在绘制粒子时,使用glBlendFuncSeparate
(described here)为Alpha通道使用不同的混合因子:
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
或者在将FBO绘制到屏幕上时完全关闭混合。
答案 2 :(得分:0)
为了获得纹理透明度,除了:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
你还应该保证:
使用glTexImage2D创建粒子tex时,使用格式 GL_RGBA(如果使用灰色阴影纹理,则使用GL_LUMINANCE_ALPHA)
绘制粒子纹理时,在glBindTexture命令之后,调用
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_BLEND);
而不是GL_BLEND,您可以使用正确的纹理函数,如中所述 glTexEnv参考:http://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml