OpenGL Alpha混合问题,混合忽略(也许)?

fla*_*rld 4 opengl glsl opengl-3

编辑+更好的解决方案:

如果有人遇到我遇到的问题,有两个解决方案.一个是接受的解决方案,但是,只有当你正在做的事情,我怎么适用.让我解释一下我在做什么:

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);
Run Code Online (Sandbox Code Playgroud)

在渲染循环中,我这样做:

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);
Run Code Online (Sandbox Code Playgroud)

如果我运行上面的代码,我得到这样的结果......

粒子特写:

粒子特克斯

OGL Profiler(Mac工具)的屏幕截图:

OGL Profiler的屏幕截图

没有渲染任何粒子的FBO的屏幕截图:

没有渲染任何粒子的FBO的屏幕截图

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;
}
Run Code Online (Sandbox Code Playgroud)

如果有什么我可以提供,请告诉我.

use*_*169 7

在我看来,它正在将alpha通道渲染到帧缓冲区中,因此当你编写粒子时,src alpha通道会与目标alpha通道混合,这不是你想要的.

这正是创建glblendfuncseparate()函数的原因.试试这个...

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
Run Code Online (Sandbox Code Playgroud)

因此,粒子的alpha通道将用于确定最终像素的颜色,但源和目标的alpha通道将一起添加.


Guy*_*yRT 5

我的猜测是 FBO 的 rgb 通道被正确渲染,但因为它也有一个 alpha 通道,并且它是在启用混合的情况下绘制的,最终结果的透明度不正确,粒子与宇宙飞船重叠。

在绘制粒子时,使用glBlendFuncSeparate此处描述)为 alpha 通道使用不同的混合因子:

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
Run Code Online (Sandbox Code Playgroud)

或者在您将 FBO 绘制到屏幕上时完全关闭混合。

  • 我接受了在这个答案之后发布的另一个答案,因为他/她更好地描述了问题以及 glBlendFuncSeparate 在这里做什么。这仍然是正确的答案。 (2认同)