OpenGL ES 高級進階:顏色混合

你們好,這是個人OpenGL ES 高級進階系列文章,在個人github上有一個與本系列文章對應的項目,歡迎關注,連接:github.com/kenneycode/…html

今天給你們介紹OpenGL的顏色混合,什麼是顏色混合呢?顏色混合就是把兩種顏色按某種規則混合起來獲得新的顏色,來看一張圖:git

好比咱們兩種顏色顏色,一種是純藍色ARGB(255, 0, 0, 255),一種是純綠色ARGB(255, 0, 255, 0),混合時分別各取一半,就獲得了混合後的顏色ARGB(255, 0, 127, 127),這就是顏色合混的基本概念。github

那麼何時須要用到顏色混合?咱們來看一種最多見的狀況,咱們把一張帶有透明部分的紋理渲染到另外一張紋理上,會怎樣?spa

你們可能會說,這不是很顯然嗎?透明部分會把底圖透出來,但若是你在OpenGL裏不使用顏色混合直接渲染,你會發現結果是這樣的:3d

透明部分並無把底圖透出來,這是爲何呢?由於顏色混合默認是關閉的,當沒開啓顏色混合時,把一個顏色渲染到另外一個顏色上,新的顏色就會把原顏色徹底覆蓋,從而獲得一個alpha爲0的顏色,透出了最底層的黑色。code

咱們來看看如何用顏色混合來解決這個問題,首先須要開啓顏色混合:cdn

// 啓用顏色混合
// Enable color blend
GLES30.glEnable(GLES30.GL_BLEND)
複製代碼

還須要設置混合方式,所謂混合方式的就是指定源顏色(將要渲染的顏色)和目標顏色(已經存在的底圖顏色)以何種方式進行混合,例如文章開篇時,以源顏色和目標顏色各佔0.5的方式進行混合,用式子來表示就是:xml

混合後顏色 = 源顏色 * 源因子 + 目標顏色 * 目標因子
複製代碼

OpenGL內置了多種混合方式,經過glBlendFunc()來設置,第一個參數是設置源因子,第二個參數是設置目標因子,在這裏,咱們須要這樣設置:htm

// 設置混合方式
// Set blend functions
GLES30.glBlendFunc(GLES30.GL_SRC_ALPHA, GLES30.GL_ONE_MINUS_SRC_ALPHA)
複製代碼

GL_SRC_ALPHA表示取源顏色的alpha值做爲因子,GL_ONE_MINUS_SRC_ALPHA表示取1減去源顏色的alpha值做爲因子,這樣能獲得什麼效果呢?blog

先來看看源顏色的透明部分和目標顏色(底圖顏色)的不透明部分混合,假設咱們的目標顏色是ARGB_DST=(1.0, a, b, c),源顏色是ARGB_SRC=(0.0, d, e, f)

此時:

混合後顏色 = ARGB_SRC * 0.0 + ARGB_DST * (1.0 - 0.0) = ARGB_DST
複製代碼

再來看看源顏色的不透明部分和目標顏色(底圖顏色)的不透明部分混合,假設咱們的目標顏色是ARGB_DST=(1.0, a, b, c),源顏色是ARGB_SRC=(1.0, d, e, f)

此時:

混合後顏色 = ARGB_SRC * 1.0 + ARGB_DST * (1.0 - 1.0) = ARGB_SRC
複製代碼

所以效果就是,源圖中的透明部分,渲染後的顏色徹底是底圖顏色,等於透出了底圖,源圖中的不透明部分,渲染以後的顏色徹底是源圖的顏色:

這樣就獲得了正確的效果。

咱們再來試試GL_ONE

GLES30.glBlendFunc(GLES30.GL_ONE, GLES30.GL_ONE)
複製代碼

這樣就是

混合後顏色 = ARGB_SRC * 1.0 + ARGB_DST * 1.0
複製代碼

來看效果:

還有不少種混合方式能夠設置,具體能夠查詢官方文檔:www.khronos.org/registry/Op…

內置的混合方式有時候並不能知足咱們的要求,例如要實現:

混合後顏色 = 源顏色 * 0.123 + 目標顏色 * 0.877
複製代碼

這時用內置的混合方式就不能實現,由於混合因子不能任意設置,這時能夠本身在fragment shader中實現。

代碼在我githubOpenGLESPro項目中,本文對應的是SampleColorBlend,項目連接:[github.com/kenneycode/…](github.com/kenneycode/…

感謝閱讀!

相關文章
相關標籤/搜索