编辑+更好的解决方案:
如果有人碰巧遇到我遇到的问题,有两种解决方案。一种是接受的解决方案,但这仅适用于您按照我的方式做事的情况。让我解释一下我在做什么:
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);
如果我使用上面的代码运行,我会得到这样的结果......
粒子纹理:
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;
}
如果有什么我可以提供的,请告诉我。