OpenGL渲染之裁剪-混合-抗鋸齒

裁剪

  • 只刷新屏幕上發(fā)生變化的部分可以提高渲染性能
  • OpenGL中是允許將要進(jìn)行渲染的窗口指定一個(gè)裁剪框
  • 裁剪框與窗口大小可不一樣(默認(rèn)是同樣大小且不會(huì)進(jìn)行裁剪測(cè)試)
//使用時(shí)要開啟裁剪測(cè)試函數(shù)
glEnable(GL_SCISSOR_TEST);
//關(guān)閉裁剪測(cè)試
glDisable(GL_SCISSOR_TEST);

//在執(zhí)行渲染窗口中,被稱為裁剪框的矩形是使用如下函數(shù)來指定窗口坐標(biāo)(像素)的
glScissor(GLint x,GLint y,GLsizei width,GLsizei height);
*注意:*x和y是指定裁剪框左下角,width和height為裁剪框的相應(yīng)尺寸

混合

  • OpenGL渲染時(shí)會(huì)把顏色值放在顏色緩沖區(qū),片段的深度是放在深度緩沖區(qū)的
  • 當(dāng)深度測(cè)試被關(guān)閉或者禁用時(shí),新的顏色值就會(huì)直接覆蓋顏色緩沖區(qū)中已經(jīng)存在的其他值
  • 當(dāng)深度測(cè)試被打開或者啟用時(shí),新的顏色片段只有當(dāng)它們比原來的值更接近臨近的裁剪平面時(shí)才會(huì)替換原來的顏色片段
  • 所以大多數(shù)情況下依賴于深度測(cè)試的結(jié)果:任何繪制操作不是被完全丟棄就是完全覆蓋原來的顏色值
//若打開OpenGL的混合功能(如下函數(shù)),下層顏色值就不會(huì)被清除
glEnable(GL_BLEND);//開啟后新舊顏色值在緩沖區(qū)中重新組合

組合顏色

  • 目標(biāo)顏色:已經(jīng)存在顏色緩沖區(qū)中的顏色值
  • 源顏色:作為當(dāng)前渲染命令的結(jié)果進(jìn)入緩沖區(qū)的顏色值
//當(dāng)以上混合功能被啟動(dòng)時(shí),源顏色值和目標(biāo)顏色的組合方式由以下混合方程式控制的
Cf = (Cs * S) + (Cd * D);
1. Cf:最終計(jì)算的顏色
2. Cs:源顏色
3. Cd:目標(biāo)顏色
4. S:源混合因子
5. D:目標(biāo)混合因子
上述混合因子用以下函數(shù)設(shè)置的
glBlendFunc(GLenum S,GLenum D);(S和D都是枚舉值)
截屏2020-07-23 16.26.34.png

注意:
顏色是用浮點(diǎn)數(shù)表述的(對(duì)它們加減甚至乘法也是完全合法的)

//混合函數(shù)組合例子
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

例如:如果顏色緩存區(qū)已經(jīng)有一種顏?紅色(1.0f,0.0f,0.0f,0.0f)即:?標(biāo)顏色Cd,
如果在這上面??種alpha為0.6的藍(lán)色(0.0f,0.0f,1.0f,0.6f)

Cd (目標(biāo)顏色) = (1.0f,0.0f,0.0f,0.0f);
Cs (源顏色) = (0.0f,0.0f,1.0f,0.6f);
S = 源alpha值 = 0.6f
D = 1 - 源alpha值= 1-0.6f = 0.4f

方程式Cf = (Cs * S) + (Cd * D)
等價(jià)于Cf = (Blue * 0.6f) + (Red * 0.4f)

最終的顏色:原先的紅色(目標(biāo)顏色)與后來的藍(lán)色(源顏色)進(jìn)行縮放后的組合,
且源顏色的alpha值越高,添加的源顏色成分就越多,目標(biāo)顏色所保留的成分就越少

混合函數(shù)經(jīng)常用于實(shí)現(xiàn)在其他一些不透明的物體前繪制一個(gè)透明物體的效果

改變混合方程式

  • 默認(rèn)混合方程式:Cf = (Cs * S) + (Cd * D)
//其實(shí)不止默認(rèn)方程式,有五個(gè)不同的混合方程式可以選擇,通過以下函數(shù)進(jìn)行操作
glBlendEquation(GLenum mode);
如下圖所示:
截屏2020-07-23 16.26.57.png
//除了用glBlendFunc來設(shè)置混合因子,還可以用如下函數(shù)更靈活的選擇
glBlendFuncSeparate(GLenum strRGB,GLenum dstRGB ,GLenum strAlpha,GLenum dstAlpha);

1.strRGB: 源顏色的混合因?
2.dstRGB: ?標(biāo)顏?的混合因?
3.strAlpha: 源顏?的Alpha因?
4.dstAlpha:目標(biāo)顏?的Alpha因?

**注意:**
1.glBlendFunc函數(shù)指定了源和目標(biāo)RGBA值的混合函數(shù)
2.glBlendFuncSeparate函數(shù)允許為RGB和alpha成分單獨(dú)指定混合函數(shù)

常量混合顏?
默認(rèn)初始化為?色(0.0f,0.0f,0.0f,0.0f),但可以用以下函數(shù)來修改。
void glBlendColor(GLclampf red ,GLclampf green ,GLclampf blue ,GLclampf alpha );

抗鋸齒

  • 鋸齒:絕大多數(shù)情況下,一個(gè)獨(dú)立的渲染片段將會(huì)映射到計(jì)算機(jī)屏幕上到一個(gè)像素(近似正方形的),通常可以相當(dāng)清楚地看到二種顏色的分界
  • 這種鋸齒現(xiàn)象會(huì)徹底暴露出這個(gè)圖像是計(jì)算機(jī)生成的,讓人覺得很不自然,由此OpenGL混合功能就能抗鋸齒,解決鋸齒問題
//OpenGL使用混合功能來混合片段的顏色,即把像素的目標(biāo)顏色與周圍像素的顏色進(jìn)行混合。
//(本質(zhì)上來說:在任何圖元的邊緣上,像素顏色會(huì)稍微延伸到相鄰的像素)
//開啟抗鋸齒(啟用混合功能)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_MINUS_SRC_ALPHA);

//glEnable函數(shù)對(duì)點(diǎn),直線和多邊形(任何實(shí)心圖元)進(jìn)行抗鋸齒處理
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);//對(duì)多邊形處理還是比較復(fù)雜的,單獨(dú)使用此方法效果并不好,大都被如下的多重采樣方法所代替

多重采樣

  • 抗鋸齒能夠使多邊形的邊緣更為平滑,使渲染效果顯得更為自然和逼真
  • 但是多邊形的平滑處理并沒有在所有的平臺(tái)上都得到實(shí)現(xiàn),即使使用GL_POLYGON_SMOOTH也沒有想象中的方便
  • 抗鋸齒處理是基于混合操作的,需要從前到后對(duì)所有的圖元進(jìn)行排序,但這是非常麻煩的

  • 鑒于以上原因,OpenGL(1.3)新增了==多重采樣==新特性來更方便的解決以上問題
  • OpenGL實(shí)現(xiàn)支持這個(gè)特性就會(huì)添加一個(gè)額外的緩沖區(qū)其包含了顏色,深度和模版值的幀緩沖區(qū)
  • 所有的圖元在每個(gè)像素上都進(jìn)行了多次采樣,其結(jié)果就存儲(chǔ)在這個(gè)緩沖區(qū)中
  • 每次當(dāng)這個(gè)像素進(jìn)行更新時(shí),這些采樣值進(jìn)行解析,以產(chǎn)生一個(gè)單獨(dú)的值

注意:
以上處理會(huì)帶來額外的內(nèi)存和處理器開銷,有可能對(duì)性能造成影響。因此,有些OpenGL實(shí)現(xiàn)可能并不支持多渲染環(huán)境中的多重采樣

多重采樣使用
  • 為了進(jìn)行多重采樣,首先必須獲得一個(gè)支持多重采樣幀緩沖區(qū)的渲染環(huán)境(這在不同的平臺(tái)中可能各不相同)
  • 但是GLUT提供一個(gè)段位(GLUT_MULTISAMPLE),允許請(qǐng)求這種幀緩沖區(qū)
  • 為了請(qǐng)求一個(gè)多重采樣,完全顏色,帶深度的雙緩沖幀緩沖區(qū),調(diào)用以下函數(shù)
gluInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);

//打開多重采樣
glEnable(GL_MULTISAMPLE);
//關(guān)閉多重采樣
glDisable(GL_MULTISAMPLE);
注意:多重采樣被啟用時(shí),點(diǎn),直線和多邊形的平滑特性都將被忽略(如果這些特性被啟用的話),
就是說在使用多重采樣時(shí),不能同時(shí)使用點(diǎn)和直線點(diǎn)平滑處理。
在一種特定的OpenGL實(shí)現(xiàn)中,點(diǎn)和線如果采用平滑處理可能會(huì)比使用多重采樣效果好(因此可以關(guān)閉多重采樣)
glDisable(GL_MULTISAMPLE);
glEnable(GL_POINT_SMOOTH);

在繪制其他實(shí)心幾何圖形時(shí)再打開多重采樣
glDisable(GL_POINT_SMOOTH);
glEnable(GL_MULTISAMPLE);

如果沒有多重采樣緩沖區(qū),OpenGL就當(dāng)作GL_MULTISAMPLE是被禁用的

打開或關(guān)閉不同的OpenGL特性將會(huì)修改驅(qū)動(dòng)程序的內(nèi)部狀態(tài),這種狀態(tài)的改變可能會(huì)對(duì)渲染的性能造成影響。對(duì)性能非常敏感程序員常常會(huì)對(duì)所有繪圖命令進(jìn)行排序,這樣需要相同狀態(tài)的幾何圖形就可以一起繪制。這種狀態(tài)排序是在游戲中常用的提高速度的方法之一


  • 多重采樣緩沖區(qū)在默認(rèn)情況下使用片段點(diǎn)RGB值,并不包括顏色的alpha成分。可以通過調(diào)用glEnable(使用如下三個(gè)值之一)來修改這個(gè)行為
GL_SAMPLE_ALPHA_TO_COVERAGE //使用alpha值
GL_SAMPLE_ALPHA_TO_ON //將alpha值設(shè)置為1并使用
GL_SAMPLE_COVERAGE //使用glSampleConverage所設(shè)置的值
當(dāng)使用最后一個(gè)時(shí),glSampleConverage函數(shù)允許指定一個(gè)特定的值,它是與片段覆蓋值進(jìn)行按位與操作的結(jié)果
glSampleConverage(GLclampf value,GLboolean invert);

注:本文參考:OpenGL超級(jí)寶典第五版

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容