OpenGL--深度測(cè)試、多邊形偏移、混合

1、深度測(cè)試

深度就是在OpenGL坐標(biāo)系中,像素點(diǎn)的Z坐標(biāo)距離觀察者的距離。

如果觀察者在Z軸的正方向,Z值越大則越靠近觀察者;

如果觀察者在Z軸的負(fù)方向,Z值越小則越靠近觀察者;

注意:以上兩種情況的坐標(biāo)系都是相對(duì)于物體的坐標(biāo)系,而不是觀察者。

深度緩沖區(qū)(Depth Buffer)

深度緩存區(qū)是指一塊專(zhuān)門(mén)內(nèi)存區(qū)域,存儲(chǔ)在顯存中,用于存儲(chǔ)屏幕上所繪制圖形的每個(gè)像素點(diǎn)的深度值。

深度值越大,離觀察者越遠(yuǎn);

深度值越小,里觀察者越近;

深度緩沖區(qū)原理

將深度值與屏幕上的每個(gè)像素點(diǎn)進(jìn)行一一對(duì)應(yīng),然后將深度值存儲(chǔ)到深度緩沖區(qū)。

在深度緩存區(qū)中,每個(gè)像素點(diǎn)只會(huì)記錄一個(gè)深度值;

深度緩沖區(qū)的范圍是[0, 1]之間,默認(rèn)值是1.0,表示深度值的最大值;

之前的demo中,在RenderScene函數(shù)繪制前,都會(huì)先清空緩存區(qū),這里的緩沖區(qū)就包括深度緩沖區(qū)與顏色緩沖區(qū),因?yàn)槿绻彺鎱^(qū)不清空,之前的數(shù)據(jù)會(huì)有殘留,會(huì)對(duì)目前圖形的繪制造成影響。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

深度測(cè)試

在繪制一個(gè)物體表面時(shí),?先會(huì)將物體表?對(duì)應(yīng)的像素的深度值與當(dāng)前深 度緩沖區(qū)中的值進(jìn)??較,如果?于深度緩沖區(qū)中的值,則丟棄這部分。否則利?這個(gè)像素對(duì)應(yīng)的深度值和顏?值,分別更新深度緩沖區(qū)和顏?緩存區(qū)。

// 在繪制場(chǎng)景前,清除顏?緩存區(qū),深度緩沖

glClearColor(0.0f,0.0f,0.0f,1.0f);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// 開(kāi)啟深度測(cè)試

glEnable(GL_DEPTH_TEST);

// 關(guān)閉深度測(cè)試

glDisable(GL_DEPTH_TEST);

// 打開(kāi)/關(guān)閉深度緩沖區(qū)寫(xiě)入 ,GL_FALSE: 關(guān)閉寫(xiě)入 GL_TRUE:打開(kāi)寫(xiě)入[圖片上傳中...(GLEnum mode.png-ccee42-1594522176751-0)]

glDepthMask(GLBool value);

// 指定深度測(cè)試判斷模式,默認(rèn)GS_LESS,當(dāng)前深度值 < 存儲(chǔ)深度值時(shí)通過(guò)

glDepthFunc(GLEnum mode);


深度測(cè)試應(yīng)用場(chǎng)景


在繪制甜甜圈demo中,當(dāng)旋轉(zhuǎn)時(shí),就會(huì)出現(xiàn)上圖甜甜圈缺口的情況,其原因是OpenGL無(wú)法區(qū)分物體的兩部分重疊情況,導(dǎo)致缺口出現(xiàn)。此時(shí),就可以通過(guò)深度測(cè)試來(lái)解決,即隱藏面的消除。修復(fù)后結(jié)果圖如下所示:


隱藏面消除方案 總結(jié)

正背面消除:需要根據(jù)頂點(diǎn)數(shù)據(jù)順序判斷用戶(hù)可見(jiàn)部分與隱藏面,隱藏面直接丟棄,不繪制,只繪制可見(jiàn)部分;

深度測(cè)試:可以一次性解決隱藏面消除問(wèn)題,原理是不管有多少圖層,只顯示可見(jiàn)圖層,剩余不可見(jiàn)的都丟棄;

2、多邊形偏移

Z-Fighting(Z沖突,閃爍)問(wèn)題

開(kāi)啟深度測(cè)試后,由于深度緩沖區(qū)精度有限制,導(dǎo)致深度值在誤差極小時(shí),OpenGL出現(xiàn)無(wú)法判斷的情況,導(dǎo)致出現(xiàn)畫(huà)面交錯(cuò)閃現(xiàn)的現(xiàn)象,例如下圖所示:


其問(wèn)題產(chǎn)生的主要原因是由于圖形靠的太近,導(dǎo)致無(wú)法區(qū)分出圖層先后次序。針對(duì)該問(wèn)題,OpenGL提供了一種多邊形偏移(Polygon Offset)方案。

使用多邊形偏移,主要有以下三個(gè)步驟

在繪制前,開(kāi)啟多邊形偏移;

glEnable(GL_POLYGON_OFFSET_FILL);

指定偏移量?glPolygonOffset (GLfloat factor, GLfloat units),參數(shù)一般填 -1 和 -1;

在繪制完成后,關(guān)閉多邊形偏移;

glDisable(GL_POLYGON_OFFSET_FILL);

預(yù)防ZFighting閃爍

避免兩個(gè)物體靠的太近:在繪制時(shí),插入一個(gè)小偏移;

將近裁剪面(設(shè)置透視投影時(shí)設(shè)置)設(shè)置的離觀察者遠(yuǎn)一些:提高裁剪范圍內(nèi)的精確度;

使用更高位數(shù)的深度緩沖區(qū):提高深度緩沖區(qū)的精確度(通常使?的深度緩沖區(qū)是24位的,現(xiàn)在有?些硬件使?32/64位的緩沖區(qū));

3、混合

當(dāng)開(kāi)啟深度測(cè)試后,兩個(gè)重疊的圖層中,如果有一個(gè)圖層是半透明的,另一個(gè)是非半透明,此時(shí)就不能通過(guò)深度值比較,來(lái)進(jìn)行顏色值的覆蓋,而是需要將兩個(gè)顏色進(jìn)行混合,然后存入顏色緩沖區(qū)。

使用

針對(duì)不同需求,顏色混合的使用方式有兩種

開(kāi)關(guān)方式

用于單純的將兩個(gè)圖層重疊時(shí)進(jìn)行顏色混合,這種混合并不能解決顏色的混合。在固定著色器和可編程著色器都可以使用這種方式。

//開(kāi)啟,

glEnable(GL_BlEND);

//關(guān)閉

glDisable(GL_BlEND);

開(kāi)關(guān)方式 + 混合方程式

用于處理類(lèi)似濾鏡效果的場(chǎng)景,簡(jiǎn)單描述就是將需要處理的圖片顏色和圖片上覆蓋的半透明顏色進(jìn)行混合,即兩股顏色混合,此時(shí)如果只是單純的開(kāi)關(guān)方式,已經(jīng)不能滿(mǎn)足我們的需求,需要借助混合方程式,來(lái)實(shí)現(xiàn)兩股顏色的混合。一般是在可編程著色器中片元著色器中使用。

//開(kāi)啟,

glEnable(GL_BlEND);

//設(shè)置混合因子--默認(rèn)值是 GL_SRC_ALPHA 和 GL_ONE_MINUS_SRC_ALPHA

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

//關(guān)閉

glDisable(GL_BlEND);

glBlendFunc方法中,是通過(guò)混合方程式來(lái)得到顏色的組合,默認(rèn)情況下混合方程式如下所示:

//Cf -- 最終組合的顏色值

//Cd:源顏色 -- 當(dāng)前渲染命令傳入的顏色值

//CS:目標(biāo)顏色 -- 顏色緩沖區(qū)中已經(jīng)存在的顏色值

//S:源混合因子

//D:目標(biāo)混合因子

Cf = (Cs * S) + (Cd * D)

在混合方程中,新顏色的alpha值越高,添加的新顏色成分就越高,舊顏色值值就保留的越少。

混合總結(jié)

在顏色緩沖區(qū)中,每個(gè)像素點(diǎn)只能存儲(chǔ)一種顏色;

顏色混合主要用于實(shí)現(xiàn)在不透明物體前繪制透明物體的效果;

只有上面圖層是透明時(shí),才需要開(kāi)啟顏色混合,如果不是,則沒(méi)有必要開(kāi)啟顏色混合;


引用文章:

http://www.itdecent.cn/p/2f7ae32bce2b

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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