你們好,這是個人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
中實現。
代碼在我github
的OpenGLESPro
項目中,本文對應的是SampleColorBlend
,項目連接:[github.com/kenneycode/…](github.com/kenneycode/…
感謝閱讀!