天天看點

一文詳解 OpenGL ES 紋理顔色混合

在OpenGL中繪制的時候,有時候想使新畫的顔色和已經有的顔色按照一定的方式進行混合。例如:想使物體擁有半透明的效果,或者繪制疊加光亮的效果,這時候就需要用到OpenGLES混合。

在OpenGL中繪制的時候,有時候想使新畫的顔色和已經有的顔色按照一定的方式進行混合。例如:想使物體擁有半透明的效果,或者繪制疊加光亮的效果,這時候就需要用到<code>OpenGLES混合</code>。

一文詳解 OpenGL ES 紋理顔色混合

如上圖所示,為石頭牆、綠色矩形、藍色雲彩 三個矩形混合後的展示效果。三個矩形(Z軸深度由深到淺)分别為,石頭牆、綠色矩形、藍色雲彩。

在OpenGLES中若使用混合,需要用到API函數方法(Java):

<code>void glBlendFunc( int srcfactor, int destfactor );</code>

(1) 其OpenGL函數原型為:

<code>void glBlendFunc(GLenum srcfactor, GLenum destfactor);</code>

(2) 其功能為:

控制<code>新畫上來的顔色 (source values, RGBA)</code>和 已經在<code>幀緩沖區中的顔色 (destination values, RGBA)</code>的混合時<code>源與目标 在最終顔色通道中所占的比例</code>。

(3) 方法參數

<code>srcfactor:代表源因子,即新畫上來的顔色。</code>

該參數由九個枚舉型被接受使用:

GL_ZERO,

GL_ONE,

GL_DST_COLOR,

GL_ONE_MINUS_DST_COLOR,

GL_SRC_ALPHA,

GL_ONE_MINUS_SRC_ALPHA,

GL_DST_ALPHA,

GL_ONE_MINUS_DST_ALPHA,

GL_SRC_ALPHA_SATURATE.

<code>destfactor:代表的是目标因子,即已經在幀緩沖區中的顔色。</code>

該參數由八個枚舉型被接受使用:

GL_SRC_COLOR,

GL_ONE_MINUS_SRC_COLOR,

GL_ONE_MINUS_DST_ALPHA

舉個栗子

參數含義

我們先看一個常用混合參數搭配:

以上參數搭配方式假設:

<code>(Sr, Sg, Sb, Sa)</code>代表<code>源顔色src(要繪制的顔色)</code>;

<code>(Dr, Dg, Db, Da)</code>代表<code>目标顔色Dest(緩沖區中顔色)</code>

如果源因子的不透明度為0.2(透明度0.8),alpha值的最大值為1,那麼源與目标混合後的<code>最終顔色值</code>為:

啟用混合與紋理矩形繪制順序代碼舉例:

有了上邊的例子,我們再回來看各個參數因子。

假設:

<code>(Dr, Dg, Db, Da)</code>代表<code>目标顔色Dest(緩沖區中顔色)</code>;

<code>(Kr, Kg, Kb, Ka)</code>代表緩沖區中各個通道R, G, B, A的最大值。

那麼各個參數因子所代表的值如下表所示:

混合因子

各顔色通道色彩比例值

GL_ZERO

(0,0,0,0)

GL_ONE

(1,1,1,1)

GL_SRC_COLOR

(Sr/Kr, Sg/Kg, Sb/Kb, Sa/Ka)

GL_DST_COLOR

(Dr/Kr, Dg/Kg, Db/Kb, Da/Ka)

GL_ONE_MINUS_SRC_COLOR

(1,1,1,1) - (Sr/Kr,Sg/Kg,Sb/Kb,Sa/Ka)

GL_ONE_MINUS_DST_COLOR

(1,1,1,1) - (Dr/Kr,Dg/Kg,Db/Kb,Da/Ka)

GL_SRC_ALPHA

( Sa/Ka, Sa/Ka, Sa/Ka, Sa/Ka )

GL_ONE_MINUS_SRC_ALPHA

(1,1,1,1) - (Sa/Ka,Sa/Ka,Sa/Ka,Sa/Ka)

GL_DST_ALPHA

( Da/Ka, Da/Ka, Da/Ka, Da/Ka )

(1,1,1,1) - (Da/Ka,Da/Ka,Da/Ka,Da/Ka)

GL_SRC_ALPHA_SATURATE

(min(Sa, Ka, Da)/Ka,min(Sa, Ka, Da)/Ka,min(Sa, Ka, Da)/Ka,1)

下邊以三張紋理圖檔在不同混合因子設定下的效果圖,對幾種常見的混合效果進行舉例說明。

其中 <code>離錄影機最遠</code>的為一張 <code>Alpha=1.0</code> 的<code>石頭牆</code>紋理圖;

其次 為一張 <code>Alpha=0.6</code> 的<code>藍色雲彩</code>紋理圖;

最後<code>離錄影機最近</code>的為一張 <code>Alpha=0.4</code>的綠色紋理圖。

源顔色(最後繪制的綠色矩形)參數因子為GL_ONE,目标色(緩沖區中顔色)參數因子為GL_ZERO。

這種參數因子組合<code>混合比例 (1.0, 0.0)</code>:

源顔色(最後繪制的綠色矩形)覆寫目标色(緩沖區中顔色);

目标色(緩沖區中顔色)不起作用,

其運作效果如下圖所示:

一文詳解 OpenGL ES 紋理顔色混合

源顔色(最後繪制的綠色矩形)與 目标色(緩沖區中顔色)均為GL_ONE。

這種參數因子組合<code>混合比例 (1.0, 1.0)</code>:

<code>源顔色(最後繪制的綠色矩形)</code>與 <code>目标色(緩沖區中顔色)</code>在混合時,源與目标的色彩通道<code>顔色所占的比例相同</code>。

一文詳解 OpenGL ES 紋理顔色混合

仔細觀察以上效果圖,可以看到三張圖檔疊加部分,幾乎為白色。

源顔色(最後繪制的綠色矩形)參數因子為 GL_ONE,目标色(緩沖區中顔色)參數因子為 GL_ONE_MINUS_DST_ALPHA。

這種參數因子組合<code>混合比例 (1.0, 1.0-Da/Ka)</code>:

<code>源顔色(最後繪制的綠色矩形)</code>與<code>目标色(緩沖區中顔色)</code>,在混合時取<code>源顔色</code>與<code>(1- Da/Ka)比例</code>進行混合。

一文詳解 OpenGL ES 紋理顔色混合

觀察以上效果圖:可以看到最上邊綠色矩形占最終混合顔色的比例較高。

三張紋理繪制時:

前兩張紋理混合時:源顔色為<code>藍色雲彩紋理矩形</code>,目标顔色為<code>石頭牆紋理矩形</code>。

由于混合比例為 (1.0, 1.0-Da/Ka),混合後的最終顔色隻顯示<code>藍色雲彩紋理矩形</code>(石頭牆紋理的ALPHA=1.0,最終石頭牆顔色所占的比例 1.0-1.0=0.0,比例為0)。

其次<code>綠色紋理矩形</code>與<code>緩沖區中顔色</code>進行混合:源顔色為<code>綠色紋理矩形</code>,目标顔色為<code>緩沖區中顔色</code>。

混合後的最終顔色基本隻顯示<code>綠色紋理矩形</code>(藍色雲彩紋理矩形的ALPHA=0.6,(1-0.6)雲紋理與綠色矩形混合後,幾乎看不到雲紋理的顔色)。

源顔色(最後繪制的綠色矩形)參數因子為 GL_SRC_ALPHA,目标色(緩沖區中顔色)參數因子為 GL_ONE。

這種參數因子組合<code>混合比例 (Sa/Ka, 1.0)</code>:

<code>源顔色(最後繪制的綠色矩形)</code>與<code>目标色(緩沖區中顔色)</code>,在混合時以源顔色值乘以Sa/Ka與目标顔色值相加。

一文詳解 OpenGL ES 紋理顔色混合

觀察以上效果圖,可以看出目标牆面與雲紋理混合後牆面紋理顔色值所占比例較高,三個紋理圖檔疊加部分有些像素點為白色。

這種方式是最常用的混合方式,源顔色(最後繪制的綠色矩形)參數因子為 GL_SRC_ALPHA,目标色(緩沖區中顔色)參數因子為 GL_ONE_MINUS_SRC_ALPHA。

這種參數因子組合<code>混合比例 (Sa/Ka, 1.0-Sa/Ka)</code>:

<code>源顔色(最後繪制的綠色矩形)</code>與 <code>目标色(緩沖區中顔色)</code>在混合時,取源顔色的 (Sa/Ka) 與目标顔色 (1.0-Sa/Ka) 相加計算最終的顔色值。

一文詳解 OpenGL ES 紋理顔色混合

案例源碼下載下傳位址:

https://download.csdn.net/download/aiwusheng/64038379

一文詳解 OpenGL ES 紋理顔色混合