剔除重複 WebGL 遮擋剔除和深度測試

2021-10-25 12:22:07 字數 3009 閱讀 7025

該demo的執行結果

上次介紹了索引快取,以及使用ibo來繪圖,使用索引快取可以迴圈利用重複的頂點,能夠提高繪圖效率。這之後的文章,如果沒有特殊的原因的話,基本上都會使用索引快取,通過drawelements來繪圖。

這次來說一下遮擋剔除和深度測試,這是兩個重要的概念,內容並不是那麼難。

首先來看遮擋剔除,如果看過之前的文章,應該知道[遮擋剔除]的概念,之前的文章

卡菲吉斯:webgl-頂點和多邊形​zhuanlan.zhihu.com

中有過說明。

簡單的說,遮擋剔除就是以多邊形內外側為基準,判斷是否繪製這個多邊形。而多邊形的內側和外側的判斷方法,在之前的文章中已經詳細說明了。為了加深印象,這裡再說一遍。

webgl中,預設規定遮擋剔除是無效的,無論以怎樣的順序來定義頂點都會繪製全部的多邊形。但是,遮擋剔除有效的時候,只有滿足特定的條件的多邊形才會進行繪製,看不見的部分是不會繪製的,這樣就會減弱座標計算等負擔。

為了設定webgl中的遮擋剔除為有效,需要像enable函式中傳入適當的引數,這個enable函式不光是用來控制遮擋剔除的,還有其他很多各種各樣的引數,根據指定的引數不同會把相應的功能設定為有效。將遮擋剔除設定為有效的話,需要傳入內建常量gl.cull_face ,下面是**舉例。

gl.enable(gl.cull_face);
相反的,將相應的功能設定為無效的話,使用disable函式,傳入的引數和enable函式相同。

遮擋剔除的內側和外側切換的方法
多邊形的內側和外側是根據頂點的連線順序來判斷的,而這個判斷基準反過來的情況也是有的,形成多邊形的頂點的連線順序是順時針的時候是外側,逆時針的時候為內側,想要反過來判斷的話,順時針就變成了內側。

順時針統稱為cw,因為[順時針]的英語是clockwise,cw就是它的頭文字。而逆時針統稱為ccw,因為[逆時針]的英語為counterclockwise。改變webgl中遮擋剔除的內側和外側的判斷標準的函式是frontface,引數就是剛才提到的cw和ccw。

將順時針設定為[外側]的**:gl.frontface(gl.cw);

將順時針設定為[內側]的**:gl.frontface(gl.ccw);

接著來說深度測試。

剛才提到的設定遮擋剔除的函式enable,也可以用來設定深度有效,將常量gl.depth_test作為引數傳給enable函式的話,就可以將深度測試設定為有效,同樣的,使用disable函式可以將其設定為無效。

深度測試的預設值是無效的,那將深度測試設定為有效有什麼用處呢,為什麼要設定深度有效呢?

深度測試可以聯想到[深度]這個詞,三維空間中表示向裡的方向時是必不可少的乙個元素,directx中叫做z測試,要表示乙個物體在你面前呢,還是向里一段距離呢,所以深度測試就是必須的了。

webgl中發出繪圖命令的時候,是在乙個模擬的三維空間中繪製模型的,這時候根據繪製的先後順序,先繪製的東西會被後繪製的東西覆蓋掉,這跟物體是在當前還是在裡面是沒關係的。而實際上,在遠處的物體應該被在近處的物體所覆蓋。

將深度測試設定為有效的話,就是對模型的深度進行評價,評價合格的東西會繪製到畫面上,不合格的東西就不會進行繪製了。

和剛才的遮擋剔除一樣,將深度測試設定為有效或無效使用的是enable函式和disable函式。

gl.enable(gl.depth_test);
深度測試的評價函式為depthfunc,這個函式需要指定引數,一般是使用下面的常量作為引數。

gl.depthfunc(gl.lequal);
這裡指定了內建常量gl.lequal的話,就會把裡側的東西隱藏,反過來想一下,基本上不會指定成其他情況了吧。

這次,介紹了遮擋剔除和深度測試,無論那乙個都是使用enable函式來設定有效,使用disable函式來設定無效。enable和disable這兩個函式的引數是一致的,根據傳入的引數不同,可以設定各種屬性設定為有效或者無效。

遮擋剔除設定為有效的話,內側的多邊形就不會描畫了,這樣就減輕了繪圖的負擔。深度測試在模擬有深度概念的三維空間時有著非常重要的作用,指定為正確的評價方法的話,就能像現實世界一樣,近處的物體會將遠處的物體遮擋住。

這次做的demo,可以自由切換遮擋剔除的有效和無效,而且可以自由指定多邊形的內測和外側,demo頁面的單選框選中或者不選,可以切換相應的狀態,而深度測試也時可以自由切換有效或是無效的,可以通過實際操作來觀察一下,深入理解一下遮擋剔除和深度測試。

demo中繪製了四個角的多邊形,一共繪製了兩個四邊形,乙個是沿著x軸旋轉,另乙個是沿著y軸旋轉,並且這兩個四邊形都繞著原點進行著旋轉移動,將深度測試設定為有效的話,裡面的四邊形就會被外面的四邊形遮住了。

仔細看demo的**的話,就應該能知道,這兩個四邊形都分別是乙個面向裡側,乙個面向外側的三角形組成的。這樣的話,將遮擋剔除設定為有效的話,多邊形的上下部分就只能繪製乙個了。

頂點的連線順序,看一下定義的索引快取的陣列的話,就明白了,下面是**。

// 儲存頂點屬性的陣列

var position = [

0.0, 1.0, 0.0,

1.0, 0.0, 0.0,

-1.0, 0.0, 0.0,

0.0, -1.0, 0.0];

// 儲存頂點的索引的陣列

var index = [

0, 1, 2,

1, 2, 3

];

看一下上面的圖和**,然後比較一下,就明白是定義了面向內側和外側兩個三角形來生成四邊形了。這是為了測試遮擋剔除而專門這麼定義的。正常來說,製作3d模型的時候,是不會像這樣將裡側和外側混在一起定義的,否則用遮擋剔除的話,模型就會出現穿孔了。

這次的demo可以通過下面的鏈結來測試。

wgld.org webgl sample 007​wgld.org

WebGL入門 十九,遮擋剔除和深度測試

注 文章譯自 原作者杉本雅広 本次的demo的執行結果 上次介紹了索引快取。以及使用ibo來畫圖,使用索引快取能夠迴圈利用反覆的頂點,能夠提高畫圖效率。這之後的文章,假設沒有特殊的原因的話。基本上都會使用索引快取,通過drawelements來畫圖。這次來說一下遮擋剔除和深度測試,這是兩個重要的概念...

Unity中的優化 遮擋剔除

遮擋剔除 當乙個物體被其他物體遮擋住而不再攝像機的可視範圍內時部隊其進行渲染 在檢視面板,你需要標識所有需要應用遮擋剔除的場景物體,最快的方法時選擇多個想要遮擋剔除計算的物體,然後標記它們為occludee static和occlusion static 乙個普通物體可以設定這裡兩個狀態 地形不能 ...

Unity3D InstantOC遮擋剔除

instantoc 外掛程式 圖形資料在gpu上經過運算處理,最後輸出到螢幕的過程。對於顯示出來的圖形,cpu與gpu的分工 cpu判斷需要顯示的圖形影象 呼叫圖形api 繪製呼叫 draw call 每次引擎準備資料並通知gpu的過程,即每幀呼叫顯示卡渲染物體的次數。即下圖中的batches。3....