深度測試
深度緩沖(Depth Buffer)存儲每個(gè)片段的信息,深度緩沖由窗口系統(tǒng)自動創(chuàng)建并將其深度值存儲為 16、 24 或 32 位浮點(diǎn)數(shù)付翁。在大多數(shù)系統(tǒng)中深度緩沖區(qū)為24位筛欢。
GLSL的片段著色器中內(nèi)置gl_FragCoord變量的 x 和 y 表示該片段的屏幕空間坐標(biāo) ,z 表示片段的實(shí)際深度值战秋。此 z 坐標(biāo)值是與深度緩沖區(qū)的內(nèi)容進(jìn)行比較的值璧亚。當(dāng)深度測試啟用的時(shí)候, OpenGL 測試深度緩沖區(qū)內(nèi)的深度值脂信,如果此測試通過癣蟋,深度緩沖內(nèi)的值將被設(shè)為z。如果深度測試失敗狰闪,則丟棄該片段疯搅。
開啟深度測試:glEnable(GL_DEPTH_TEST);
清除深度緩沖區(qū):GL_DEPTH_BUFFER_BIT
禁用深度緩沖區(qū)寫入:glDepthMask(GL_FALSE);
深度測試函數(shù)
glDepthFunc(GL_LESS);
深度值精度
這里far和near是投影矩陣設(shè)置的可見視圖截錐的遠(yuǎn)近平面值
z值超過一定值,深度值的變化較谐⒍摺(絕對值較大)秉撇,反映的是觀察者不太會注意遠(yuǎn)離近平面時(shí)物體的細(xì)節(jié)的經(jīng)驗(yàn)。
深度緩沖區(qū)的可視化
將片段的z值作為顏色輸出秋泄,可以反映深度值隨z的變化呈現(xiàn)出的明暗變化琐馆。
深度沖突
兩個(gè)平面或三角形緊密相互平行,深度緩沖區(qū)不具有足夠的精度恒序,無法得知哪一個(gè)靠前瘦麸,導(dǎo)致這兩個(gè)形狀不斷切換順序。這被稱為深度沖突(Z-fighting)歧胁,因?yàn)樗瓷先ハ裥螤顮帄Z靠前的位置滋饲。當(dāng)對象的距離越遠(yuǎn)沖突一般越強(qiáng)(因?yàn)樯疃染彌_區(qū)在z值非常大的時(shí)候沒有很高的精度)。
防止深度沖突
1喊巍,讓物體之間不要離得太近
2屠缭,盡可能把近平面設(shè)置得遠(yuǎn)一些,使得位于近平面附近具有更高的深度值精度
3崭参,大多數(shù)的深度緩沖區(qū)都是24位呵曹,若顯卡支持32位深度值,可提高深度緩沖區(qū)的精度
模板測試
模板測試(Stencil Test)位于片段著色器之后何暮,深度測試之前奄喂,通過設(shè)置模板緩沖(Stencil Buffer)可以保留或丟棄一些片段。
模板緩沖中的模板值(Stencil Value)通常是8位的海洼,因此每個(gè)片段/像素共有256種不同的模板值跨新。
模板緩沖先清空模板緩沖,設(shè)置所有片段的模板值為0坏逢,然后需要渲染的矩形片段用1填充域帐。場景中的模板值為1的那些片段才會被渲染(其他的都被丟棄)赘被。
1,開啟模板緩沖寫入俯树。glEnable(GL_STENCIL_TEST);
2帘腹,渲染物體,更新模板緩沖许饿。
3,關(guān)閉模板緩沖寫入舵盈。
4陋率,渲染(其他)物體,這次基于模板緩沖內(nèi)容丟棄特定片段秽晚。
每次渲染之前需清空模板緩沖:GL_STENCIL_BUFFER_BIT
設(shè)置模板位掩碼(Bitmask):glStencilMask(value);設(shè)置此值可以屏蔽某些模板緩沖位置的可寫性(模板值與value與運(yùn)算的結(jié)果是最后的模板值)瓦糟。
模板函數(shù)
void glStencilFunc(GLenum func, GLint ref, GLuint mask);
func:設(shè)置模板測試操作。這個(gè)測試操作應(yīng)用到已經(jīng)儲存的模板值和ref值上赴蝇,可用的選項(xiàng)是:GL_NEVER菩浙、GL_LEQUAL、GL_GREATER句伶、GL_GEQUAL劲蜻、GL_EQUAL、GL_NOTEQUAL考余、GL_ALWAYS先嬉。它們的語義和深度緩沖的相似。
ref:指定模板測試的引用值楚堤。模板緩沖的內(nèi)容會與這個(gè)值對比疫蔓。
mask:指定一個(gè)遮罩,在模板測試對比引用值和儲存的模板值前身冬,對它們進(jìn)行按位與(and)操作衅胀,初始設(shè)置為1。
void glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass);
sfail: 如果模板測試失敗將采取的動作酥筝。
dpfail: 如果模板測試通過滚躯,但是深度測試失敗時(shí)采取的動作。
dppass: 如果深度測試和模板測試都通過樱哼,將采取的動作哀九。
默認(rèn)值都是GL_KEEP,即不會更新模板緩沖搅幅。
物體輪廓
物體輪廓(Object Outining)它能夠給每個(gè)(或一個(gè))物體創(chuàng)建一個(gè)有顏色的邊阅束。在策略游戲中當(dāng)你打算選擇一個(gè)單位的時(shí)候它特別有用。給物體加上輪廓的步驟如下:
1茄唐,在繪制物體前息裸,把模板測試方程設(shè)置為GL_ALWAYS蝇更,用1更新物體將被渲染的片段。
2呼盆,渲染物體年扩,寫入模板緩沖。
3访圃,關(guān)閉模板寫入和深度測試厨幻。
4,每個(gè)物體放大一點(diǎn)點(diǎn)腿时。
5况脆,使用一個(gè)不同的片段著色器用來輸出一個(gè)純顏色。
6批糟,再次繪制物體格了,但只是當(dāng)它們的片段的模板值不為1時(shí)才進(jìn)行。
7徽鼎,開啟模板寫入和深度測試盛末。
圖片和一些文字來源于https://learnopengl-cn.github.io,本人收集作為筆記否淤,如有侵權(quán)悄但,望告知