2013-06-20 114 views
1

編輯+更好的解決方案:OpenGL Alpha混合問題,混合忽略(也許)?

如果有人遇到我遇到的問題,有兩種解決方案。一個是接受的解決方案,但只適用於你正在做的事情如何我。讓我來解釋我在做什麼:

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); 

如果我運行用上面的代碼,我得到這樣的結果...

Particle tex:

Particle tex

從OGL探查(蘋果機工具)截圖:所述FBO的

Screenshot from OGL Profiler

截圖而不呈現任何顆粒:

Screenshot of the FBO without any particle rendered

的FBO的屏幕截圖的一些顆粒呈現在頂部:

Screenshot of the FBO with some particles rendered on top

如您所見,粒子儘管具有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; 
} 

讓我知道是否有任何我可以提供。

回答

4

我看來像它被渲染alpha通道以及到幀緩衝器中,所以,當你寫出粒子,src alpha通道與目標alpha通道混合在一起,這不是你想要的。

這正是創建glblendfuncseparate()函數的原因。試試這個...

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); 

所以,你的粒子的alpha通道將被用來確定最終像素的顏色,但在源和目的地的alpha通道將被添加到一起。

2

我的猜測是FBO的RGB通道正在渲染正確,但是因爲它也有一個alpha通道,並且它正在繪製時啓用了混合,所以最終的結果是粒子與飛船重疊的透明度不正確。

要麼使用glBlendFuncSeparatedescribed here)使用不同的混合因子alpha通道,當你繪製的粒子:

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); 

或關閉,當你畫你的FBO在屏幕上完全融合。

+0

我接受了另一個答案,在這之後發佈了其他答案,因爲他/她更好地描述了問題以及glBlendFuncSeparate在此處做了什麼。這仍然是正確的答案。 – teh1

0

爲了獲得紋理的透明度,除了:

glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 

也應確保:

  1. 創建與glTexImage2D顆粒TEX時

    ,用作格式 GL_RGBA(或GL_LUMINANCE_ALPHA如果使用灰色陰影紋理)

  2. 繪製粒子紋理時,尾部呃glBindTexture命令,請致電

    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_BLEND);

相反GL_BLEND的,如在 的glTexEnv說明可以使用正確的紋理功能:http://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml

+0

不正確。我專門爲我的問題標記了'opengl-3'。此功能適用於小於3的版本。 – teh1

+0

LOL我大量使用OpenGL SC,所以我非常瞭解這個版本。我的錯沒有注意到opengl-3標籤。 – Zac