[英]Blending issue porting from OpenGLES 1.0 to 2.0 (iOS)
我正在將一段非常簡單的代碼從OpenGLES 1.0移植到OpenGLES 2.0。
在原始版本中,我啟用了
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
我在ES 2.0實現中使用了相同的代碼,因為我需要將新渲染的四邊形與渲染緩沖區中的內容混合在一起(我保留了渲染緩沖區,無法重新渲染場景)。
我使用的紋理(alpha值顯示從中心到外部的徑向漸變,alpha從1到0)用作alpha蒙版,僅包含具有不同alpha值的白色像素。 我給我的頂點用相同的顏色說紅色,alpha為100/255。 我的背景是透明的黑色。 在此之下,我有一個純白色的表面(UIView)。 我渲染4個四邊形。
OpenGLES 1.0的結果(理想結果)
我的觀察告訴我片段着色器應該簡單地是:
gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut);
(我通過為頂點和紋理嘗試不同的值來得出這個結論。這也是我在某些教程中所讀到的。)
我正在嘗試編寫一些OpenGL 2.0代碼(包括頂點+片段着色器),這些代碼將為我提供與OpenGLES 1.0完全相同的結果,僅此而已。 除了在紋理上應用頂點顏色外,我不需要/不想在片段着色器中進行任何類型的混合。 使用簡單的着色器,這是我得到的結果:
我嘗試了幾乎可以想到的*,+,混合的每種組合,但無法重現相同的結果。 這是我到目前為止獲得的最接近的距離,但這絕對不是正確的位置(而且也沒有任何意義)
varying lowp vec4 DestinationColor;
varying lowp vec2 TexCoordOut;
uniform sampler2D Texture;
void main(void) {
lowp vec4 texture0Color = texture2D(Texture, TexCoordOut);
gl_FragColor.rgb = mix(texture0Color.rgb, DestinationColor.rgb, texture0Color.a);
gl_FragColor.a = texture0Color.a * DestinationColor.a;
}
該着色器為我提供了以下內容:
由於您使用的是glBlendFunc
而不是glBlendFuncSeparate
,因此將混合所有4個通道。 使用GL_FUNC_ADD
參數將輸出O設置為O = sS + dD
,其中s
和d
是混合參數, S
和D
是源色和目標色。
s
和d
參數由glBlendFunc
設置。 GL_ONE
將s
設置為(1, 1, 1, 1)
GL_ONE_MINUS_SRC_ALPHA
(1, 1, 1, 1)
,而GL_ONE_MINUS_SRC_ALPHA
將d
設置為(1-As, 1-As, 1-As, 1-As)
,其中As
是源的alpha值。 因此,您的混合正在執行此操作(矢量形式):
O = S + (1-As) * D
在GLSL
為O = mix(D, S, As)
或: gl_FragColor = mix(DestinationColor, TexCoordOut, As)
。
如果結果看起來不相似,請確認您沒有使用glBlend
或任何其他可能改變最終結果外觀的OpenGL API。 如果這樣做沒有幫助,請發布不同輸出的屏幕截圖。
使用混合器很難做到這一點,因為混合必須讀取當前的幀緩沖區狀態。 您可以通過渲染到紋理並將其傳遞給着色器來實現,如果可以將顏色保存在幀緩沖區中,則可以。
你的方程是:
gl_FragColor = wouldBeFramebufferColor + (1-wouldBeFramebufferColor.a) * texture0Color;
但是為什么要在着色器中做到這一點在OpenGL ES 2.0中並未刪除AFAIK混合
愚蠢的錯誤。 當我傳入無符號字節時,我只需要在頂點着色器中標准化頂點顏色。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.