OpenGL 混合使用、算法和計(jì)算

混合簡介

混合在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传蹈。
  1. f_source是輸入片段(源)的混合因子;
  2. C_source是輸入片段(源)的顏色步藕;
  3. f_destination是目標(biāo)像素(目標(biāo))的混合因子惦界;
  4. C_destination是目標(biāo)像素(目標(biāo))的顏色;
  5. 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ù)的文章中將以例子的形式介紹在著色器中使用混合纱注。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末畏浆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子狞贱,更是在濱河造成了極大的恐慌刻获,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瞎嬉,死亡現(xiàn)場離奇詭異蝎毡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)氧枣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門沐兵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人挑胸,你說我怎么就攤上這事痒筒。” “怎么了茬贵?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵簿透,是天一觀的道長。 經(jīng)常有香客問我解藻,道長老充,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任螟左,我火速辦了婚禮啡浊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胶背。我一直安慰自己巷嚣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布钳吟。 她就那樣靜靜地躺著廷粒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坝茎,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天涤姊,我揣著相機(jī)與錄音,去河邊找鬼嗤放。 笑死思喊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的次酌。 我是一名探鬼主播恨课,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼和措!你這毒婦竟也來了庄呈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤派阱,失蹤者是張志新(化名)和其女友劉穎诬留,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贫母,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡文兑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腺劣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绿贞。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖橘原,靈堂內(nèi)的尸體忽然破棺而出籍铁,到底是詐尸還是另有隱情,我是刑警寧澤趾断,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布拒名,位于F島的核電站,受9級(jí)特大地震影響芋酌,放射性物質(zhì)發(fā)生泄漏增显。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一脐帝、第九天 我趴在偏房一處隱蔽的房頂上張望同云。 院中可真熱鬧,春花似錦堵腹、人聲如沸炸站。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旱易。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咒唆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來泰國打工释液, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留全释,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓误债,卻偏偏與公主長得像浸船,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子寝蹈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容