混合簡介
混合在OpenGL的多圖層疊加和緩沖區(qū)顏色計(jì)算中必不可少。開發(fā)人員可以通過OpenGL自帶的混合接口進(jìn)行混合萌业,也可以在著色器中自定義相關(guān)混合算法進(jìn)行融合。本文將詳細(xì)講解OpenGL自帶的混合算法的計(jì)算方法奸柬,幫助需要進(jìn)行顏色混合處理操作的開發(fā)人員快速了解混合算法中的各項(xiàng)含義和計(jì)算方法生年,并簡要講解兩種混合方式的實(shí)現(xiàn)。
基本概念
- 輸入片段的顏色和Alpha通常稱為源顏色分量和源Alpha廓奕,目標(biāo)像素的顏色和Alpha則稱為目標(biāo)顏色分量和目標(biāo)Alpha抱婉。在混合過程中档叔,是將新渲染的顏色-輸入片段-src(源)與現(xiàn)有的顏色-目標(biāo)像素-dst(目標(biāo))進(jìn)行混合,通過計(jì)算將最終的混合結(jié)果呈現(xiàn)在屏幕上蒸绩。通俗點(diǎn)介紹即源是指新渲染需要混合的顏色衙四,目標(biāo)是指緩沖區(qū)中現(xiàn)有的、將要被混合的顏色患亿。
- 混合方程式為C_final = f_source * C_source op f_destination * C_destination传蹈。
- f_source是輸入片段(源)的混合因子;
- C_source是輸入片段(源)的顏色步藕;
- f_destination是目標(biāo)像素(目標(biāo))的混合因子惦界;
- C_destination是目標(biāo)像素(目標(biāo))的顏色;
- op是混合運(yùn)算符咙冗,可以是GL_FUNC_ADD(前后兩項(xiàng)相加)沾歪,GL_FUNC_SUBTRACT(前后兩項(xiàng)相減),GL_FUNC_REVERSE_SUBTRACT(前后兩項(xiàng)相減乞娄,但順序相反)瞬逊。
混合使用
快速使用混合只需要以下四步:
- 啟用混合模式
glEnable(GL_BLEND)
; - 設(shè)置混合函數(shù)
glBlendFunc(GLenum sfactor,GLenum dfactor)
仪或; - 指定混合運(yùn)算符
glBlendEquation(GLenum mode)
确镊; - 關(guān)閉混合模式
glDisable(GL_BLEND)
(在無需使用混合的結(jié)尾調(diào)用);
再深入使用
- 設(shè)置混合函數(shù)還可以調(diào)用
glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
分別對(duì)輸入片段和目標(biāo)片段設(shè)置RGB分量和Alpha值的混合因子范删; - 指定混合運(yùn)算符還可以通過調(diào)用
glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
分別指明RGB和Alpha的混合運(yùn)算符蕾域; - 如果混合函數(shù)選擇了包含常量,如
GL_CONSTANT_COLOR
到旦,則在設(shè)置混合參數(shù)的時(shí)候還需要通過glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
設(shè)置常量顏色作為混合因子進(jìn)行計(jì)算旨巷。
混合算法
OpengGL提供了15中混合函數(shù)供開發(fā)者快速使用,包括(混合系數(shù)枚舉值添忘、混合因子采呐、注釋):
-
GL_ZERO
(0,0,0,0) 混合因子都為0; -
GL_ONE
(1,1,1,1) 混合因子都為1搁骑; -
GL_SRC_COLOR
(Rs,Gs,Bs,As) 混合因子為源顏色分量斧吐; -
GL_ONE_MINUS_SRC_COLOR
(1-Rs,1-Gs,1-Bs,1-As) 混合因子為1-C_source; -
GL_SRC_ALPHA
(As,As,As,As) 混合因子為源Alpha值; -
GL_ONE_MINUS_SRC_ALPHA
(1-As,1-As,1-As,1-As) 混合因子為1-f_source; -
GL_DST_COLOR
(Rd,Gd,Bd,Ad) 混合因子為目標(biāo)顏色分量仲器; -
GL_ONE_MINUS_DST_COLOR
(1-Rd,1-Gd,1-Bd,1-Ad) 混合因子為1-C_destination; -
GL_DST_ALPHA
(Ad,Ad,Ad,Ad) 混合因子為目標(biāo)Alpha值煤率; -
GL_ONE_MINUS_DST_ALPHA
(1-Ad,1-Ad,1-Ad,1-Ad) 混合因子為1-f_destination; -
GL_CONSTANT_COLOR
(Rc,Gc,Bc,Ac) 混合因子為常量顏色; -
GL_ONE_MINUS_CONSTANT_COLOR
(1-Rc,1-Gc,1-Bc,1-Ac) 混合因子為1-常量顏色乏冀; -
GL_CONSTANT_ALPHA
(Rc,Gc,Bc,Ac) 混合因子為常量Alpha; -
GL_ONE_MINUS_CONSTANT_ALPHA
(1-Rc,1-Gc,1-Bc,1-Ac) 混合因子為1-常量Alpha; -
GL_SRC_ALPHA_SATURATE
(min(As,1-Ad)) 混合因子為源Alpha和(1-目標(biāo)Alpha)的最小值蝶糯;
其中R指的是紅色通道、G指的是綠色通道辆沦、B指的是藍(lán)色通道昼捍、A指的是Alpha识虚、s指的是源(輸入片段),d指的是目標(biāo)(目標(biāo)像素)端三,c指的是自定義的常量舷礼。
以GL_ONE_MINUS_DST_ALPHA
為例,1-Ad指的是1-目標(biāo)Alpha郊闯。
舉例計(jì)算
例子1妻献,使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR)
在實(shí)際運(yùn)用場景中開啟混合模式。先在圖層上上繪制一個(gè)顏色W(0.3,0.4,0.7,0.5)团赁,緊接著再繪制一個(gè)顏色X(0.8,0.2,0.3,0.1)育拨。如果采用的混合函數(shù)為glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_COLOR)
,運(yùn)算符為glBlendEquation(GL_FUNC_ADD)
欢摄,其混合結(jié)果計(jì)算如下:
- 源混合函數(shù)采用
GL_SRC_ALPHA
熬丧,其混合因子是源Alpha(As,As,As,As)。計(jì)算方式為將源顏色分別乘上As=0.5怀挠,所以混合方程式的第一段f_source * C_source = (As,As,As,As) * W(0.3,0.4,0.7,0.5)=(0.5,0.5,0.5,0.5) * W(0.3,0.4,0.7,0.5) = (0.15,0.2,0.35,0.25); - 目標(biāo)混合函數(shù)采用
GL_ONE_MINUS_SRC_COLOR
析蝴,其混合因子是1-C_source。計(jì)算方式為將目標(biāo)顏色分別乘(1-源顏色)绿淋,所以混合方程式的第二段f_destination * C_destination = (1-Rs,1-Gs,1-Bs,1-As) * X(0.8,0.2,0.3,0.1) = (1-0.8,1-0.2,1-0.3,1-0.1) * X(0.8,0.2,0.3,0.1)=(0.2,0.8,0.7,0.9) * X(0.8,0.2,0.3,0.1) = (0.16,0.16,0.21,0.09); - 根據(jù)混合方程式即上述兩部分相加闷畸,即源(0.15,0.2,0.35,0.25) + 目標(biāo)(0.16,0.16,0.21,0.09) = C_final(0.31,0.36,0.56,0.34),因此混合結(jié)果輸出為該點(diǎn)最終顯示 C_final(0.31,0.36,0.56,0.34)吞滞。
例子2佑菩,使用glBlendFuncSeparate(GL_ONE,GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_DST_ALPHA)
條件和例子1中一樣,除了混合函數(shù)采用glBlendFuncSeparate(GL_ONE,GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_DST_ALPHA)
裁赠,通過分解可知
- 源顏色混合函數(shù)采用
GL_ONE
殿漠,其混合因子是(1,1,1,1)。計(jì)算方式為將源顏色分別乘1佩捞,所以混合方程式第一段f_source * C_source 中的RGB通道計(jì)算為 (1,1,1) * W(0.3,0.4,0.7) = (0.3,0.4,0.7); - 源Alpha混合函數(shù)采用
GL_ONE
绞幌,其混合因子是(1,1,1,1)。計(jì)算方式為將源Alpha乘1一忱,所以混合方程式第一段f_source * C_source 中的Alpha通道計(jì)算為(1) * (0.5) =(0.5)莲蜘,所以方程式第一段結(jié)果為(0.3,0.4,0.7,0.5); - 目標(biāo)顏色混合函數(shù)采用
GL_ONE_MINUS_SRC_ALPHA
,其混合因子是(1-As,1-As,1-As,1-As),所以混合方程式第二段f_destination * C_destination中的RGB通道計(jì)算為 (1-0.5,1-0.5,1-0.5) * X(0.8,0.2,0.3) = (0.5,0.5,0.5) * X(0.8,0.2,0.3) = (0.4,0.1,0.15); - 目標(biāo)Alpha混合函數(shù)采用
GL_ONE_MINUS_DST_ALPHA
掀潮,其混合因子是(1-Ad,1-Ad,1-Ad,1-Ad),所以混合方程式第二段f_destination * C_destination中的Alpha通道計(jì)算為(1-0.1) * *X(0.1) *= (0.9) * (0.1) = (0.09)琼富,所以方程式第二段結(jié)果為 (0.4,0.1,0.15,0.09); - 根據(jù)混合方程式即上述兩部分相加仪吧,即源(0.3,0.4,0.7,0.5) + 目標(biāo)(0.4,0.1,0.15,0.09) = C_final(0.7,0.5,0.85,0.59),因此混合結(jié)果輸出為該點(diǎn)最終顯示C_final(0.7,0.5,0.85,0.59)鞠眉。
著色器中混合
由于OpenGL自帶的混合算法接口存在一定局限性薯鼠,除了上述介紹的內(nèi)容就無法自定義擴(kuò)展择诈,因此開發(fā)人員也可以在著色器中完成混合。但這樣的做法不僅需要當(dāng)前幀的顏色緩沖數(shù)據(jù)作為著色器輸入出皇,還需要前一幀的顏色緩沖數(shù)據(jù)羞芍,從而自定義算法完成混合。因此其在時(shí)間和空間上存在一定劣勢郊艘,但換來的是高自由度荷科、可自定義的混合算法。后續(xù)的文章中將以例子的形式介紹在著色器中使用混合纱注。