2013-06-12 110 views
3

我正在將一些代碼從OpenGL ES 1.x移植到OpenGL ES 2.0,我正在努力獲得像以前一樣的透明度工作;我所有的三角形都呈現完全不透明狀態。如何在OpenGL ES 2.0中使用Alpha混合透明度?

我的OpenGL設置有這些行:

// Draw objects back to front 
glDisable(GL_DEPTH_TEST); 

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

glDepthMask(false); 

我的着色器看起來像這樣:

attribute vec4 Position; 
uniform highp mat4 mat; 
attribute vec4 SourceColor; 
varying vec4 DestinationColor; 

void main(void) { 
    DestinationColor = SourceColor; 
    gl_Position = Position * mat; 
} 

這:

varying lowp vec4 DestinationColor; 

void main(void) { 
    gl_FragColor = DestinationColor; 
} 

可能是什麼回事?

編輯:如果我在片段着色器手動在片段着色器(在頂點着色器或確實)設置alpha到0.5keaukraine below的建議,然後我得到透明的一切。 此外,如果我更改顏色值我傳遞給OpenGL浮動而不是無符號字節,然後代碼正常工作。

所以它看起來好像事情是錯被路過的色彩信息轉換成OpenGL代碼,而我仍想知道是什麼問題了。

我的頂點是這樣定義的(持平OpenGL ES的1.x的代碼):

typedef struct 
{ 
    GLfloat x, y, z, rhw; 
    GLubyte r, g, b, a; 
} Vertex; 

而且我用的是下面的代碼將它們傳遞到OpenGL的(類似的OpenGL ES 1.x的代碼):

glBindBuffer(GL_ARRAY_BUFFER, glTriangleVertexBuffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * nTriangleVertices, triangleVertices, GL_STATIC_DRAW); 
glUniformMatrix4fv(matLocation, 1, GL_FALSE, m); 
glVertexAttribPointer(positionSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x)); 
glVertexAttribPointer(colorSlot, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, r)); 
glDrawArrays(GL_TRIANGLES, 0, nTriangleVertices); 
glBindBuffer(GL_ARRAY_BUFFER, 0); 

以上是什麼問題?

回答

4

您的顏色頂點屬性值沒有被標準化。這意味着頂點着色器可以在0-255範圍內看到該屬性的值。

glVertexAttribPointer的第四個參數更改爲GL_TRUE,並按照您最初的預期對值進行歸一化(按比例縮放至範圍0.0-1.0)。

看到http://www.khronos.org/opengles/sdk/docs/man/xhtml/glVertexAttribPointer.xml

+0

現在我覺得很愚蠢。謝謝! – Rich

+0

大概不會像我當我意識到我的代碼中的一個錯誤時那樣愚蠢,使得這個標記完全未定義! – GuyRT

2

我懷疑DestinationColor改變你的片段着色器總是包含0xFF的alpha通道?如果是這樣,那是你的問題。嘗試改變,以便實際上alpha變化。

更新:我們發現2個好的解決辦法:

  1. 使用浮動,而不是用於在片段着色器提供給DestinationColor的varyings無符號字節。

  2. 或者,正如GuyRT指出的那樣,您可以將glVertexAttribPointer的第四個參數更改爲GL_TRUE,以告知OpenGL ES在從整數轉換爲浮點時對值進行規範化。

+0

我認爲它總是包含1,其實,但你是正確的,這是錯誤的,一旦它到達片段着色器。 (請參閱上面的編輯。)任何想法? – Rich

+0

輸入顏色值必須在0.0到1.0的範圍內浮動。由於您使用的是字節,因此所有大於0的整數值都將被轉換爲1.0和更高的值,這會達到1.0,從而使您完全不透明。 – ClayMontgomery

+0

謝謝!我想那是發生了什麼事,但我沒有意識到這僅僅是因爲你不能在OpenGL ES 2.0中使用無符號字節的顏色。如果您編輯您的答案以包含此信息,我會刪除我的答案並接受您的答案。 – Rich

1

要調試這種情況下,你可以嘗試設置常數α和看它是否有差別:

varying lowp vec4 DestinationColor; 

void main(void) { 
    gl_FragColor = DestinationColor; 
    gl_FragColor.a = 0.5; /* try other values from 0 to 1 to test blending */ 
} 

你也應該確保你挑選EGL配置的alpha通道。

而且不要忘了在片段着色彩車指定精度!閱讀OpenGL GL | ES 2.0的規格(http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf第4.5節。3),並請看到這個答案:https://stackoverflow.com/a/6336285/405681

+0

謝謝。這很有幫助。它看起來好像我在用無符號字節傳遞的方式做錯了什麼。 (請參閱編輯問題。)任何想法? – Rich