標籤: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