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

注:文章譯自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的額外說明,我會加上[lufy:],另外,鄙人webgl研究還不夠深入,一些專業詞語,如果翻譯有誤,歡迎大家指正。



本次的demo的運行結果


多邊形的外側,內側和遮擋剔除

上次介紹了索引緩存,以及使用IBO來繪圖,使用索引緩存可以循環利用重複的頂點,能夠提高繪圖效率。這之後的文章,如果沒有特殊的原因的話,基本上都會使用索引緩存,通過drawElements來繪圖。
這次來說一下遮擋剔除和深度測試,這是兩個重要的概念,內容並不是那麼難。
首先來看遮擋剔除,如果看過之前的文章,應該知道[遮擋剔除]的概念,之前的文章(六,頂點和多邊形)中有過說明。
簡單的說,遮擋剔除就是以多邊形內外側爲基準,判斷是否繪製這個多邊形。而多邊形的內側和外側的判斷方法,在之前的文章中已經詳細說明了。爲了加深印象,這裏再說一遍。
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的內容補充

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可以通過下面的鏈接來測試。

遮擋剔除和深度測試的demo

http://wgld.org/s/sample_007/



轉載請註明:轉自lufy_legend的博客http://blog.csdn.net/lufy_legend


發佈了86 篇原創文章 · 獲贊 91 · 訪問量 184萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章