首頁 >web前端 >js教程 >THREE.JS入門教學(2)著色器-上_基礎知識

THREE.JS入門教學(2)著色器-上_基礎知識

WBOY
WBOY原創
2016-05-16 17:43:021194瀏覽
譯序
Three.js是一個很棒的開源WebGL函式庫,WebGL允許JavaScript操作GPU,在瀏覽器端實現真正意義的3D。但目前這項技術還在發展階段,資料極為匱乏,愛好者學習基本上要透過Demo源碼和Three.js本身的源碼來學習。

0.簡介
之前我已經給了一篇《開始使用Three.js》。如果你還沒讀過,你可能需要去讀一下,本文的基礎是在那一篇教學的基礎上完成的。

我想討論一下著色器。在Three.js幫助你免去了很多麻煩之前,原生WebGL就很優秀了。有的時候,你也許會想要完成一些特定的效果,或是想對呈現在你的螢幕上的東西鑽研得更深入一些,那麼著色器一定會進入你的視野。如果你跟我一樣,你也同樣希望實現一些比上一篇教學中的基礎更有意思的東西。在這篇教程中,我會講解Three.js的基礎,這些基礎其實為我們做了很多枯燥的工作。
在開始之前我還要說,這篇教學會有相當多的篇幅在解釋著色器的程式碼,之後會有一篇教學會在著色器程式碼的基礎上前進一點,利用著色器去做點什麼。這是因為著色器shaders第一眼看起來並不易懂,需要一些解釋。
1.兩種著色器
WebGL沒有固定的渲染管線,你無法直接使用一個黑盒子式的著色器(譯者註:上個世紀的顯卡基本上都只支持固定渲染管線);WebGL提供的是可程式化的管線,這種方式更強大但也更難理解和使用。長話短說,可程式渲染管線意味著編寫程式的人要自己負責取得頂點並將它繪製在螢幕上了。著色器是渲染管線的一部分,有兩種著色器:
1.頂點著色器
2.片元著色器
你應該知道的是,這兩種著色器都完全運作在顯示卡在的GPU上,我們將需要它們處理的資料從CPU上卸下,裝到GPU上,減輕了CPU的復旦。現代的GPU對著色器所需的呼叫的運算類型都做了大幅優化,這樣做很值得。
2.頂點著色器
基元形狀,例如一個球體,是由頂點構成的,對吧?頂點著色器被依序傳入這些頂點中的一個頂點,然後處理它。如何處理每個頂點是可以自由自訂的,但頂點著色器有一個必做的事,就是為一個名為 gl_Position 的變數賦值,該變數是一個4維數組,表示該頂點最終在螢幕上的位置。這本身是個有趣的過程,因為我們實際上在談論如何將一個三維座標(一個具有x、y、z值得頂點)轉化為,或者說投影到二維的螢幕上。謝天謝地,如果我們使用Three.js之類的工具,我們能夠如此方便地存取到 gl_Position 。
3.片元著色器
現在我們有包含頂點的三維物體了,現在要將物體投影到二維螢幕上了,但顏色哪裡去了?紋理和光照呢?這正是片元著色器要處理的。
和頂點著色器類似,片元著色器有一項必須完成的任務:設定或消除變數 gl_FragColor ,另一個四維浮點變量,也就是片元點最終的顏色。什麼是片元?想像一個具有三個頂點的三角形,片元就是經過這三個頂點計算後的,所有在三角形內部的點。因此,片元值由頂點的值內插產生。如果一個頂點的顏色是紅色,相鄰頂點的顏色是藍色,那麼我們可以觀測到顏色從紅色頂點附近漸變,由紅色變成紫色,最終在藍色頂點附近變成藍色。
4.著色器變數 說到著色器變量,有三種:Uniforma,Attributes和Varyings。當我第一次聽到這三個字時,我很困惑,因為它們和我之前用到的東西完全不符。但現在,你可以這樣理解它們:
1.Uniforms變數既可以傳入頂點著色器,也可以傳入片元著色器,它們包含了哪些在整個渲染過程中保持不變的變量,例如,一個點光源的位置。
2.Attributes變數對應於每個頂點,它們只可以傳入頂點著色器中,例如每個頂點都具有一個顏色。 Attributes變數和頂點的關係是一一對應的。
3.Varyings變數是在頂點著色器中定義,並且準備傳入給片元著色器的變數。為了確保這一點,我們需要確保在兩個著色器中變數的類型和命名完全一致。一個經典的應用是法線向量,因為在計算光照的時候需要用到法線。
在後面一篇教學中,我會使用這三種變量,你也會學到這三種變數如何真正應用得。
現在,我們已經談過了頂點著色器、片元著色器和三種著色器變數。是時候來看一個我們可以創建的最簡單的著色器了。
5.Hello World(譯者吐槽:能不能不要秀法語啊)
這兒有一個最簡單的頂點著色器:
複製程式碼 程式碼如下:

/**
* 每個頂點座標乘以模型視圖矩陣在乘以投影矩陣
* 獲得在二維螢幕上的座標
*/
void main() {
gl_Position =*/
void main() {
gl_Position = projection> 🎜>modelViewMatrix *
vec4(position,1.0);
}


一個最簡單的片元著色器:
複製程式碼


程式碼如下:


/**
* 將任一像元色設定為粉紅
*/
void main() {
gl_FragColor = vec4(1.0, / / R
0.0, // G
1.0, // B
1.0); // A
}


這就是全部了。現在直接運行的話,你就可以在螢幕上看到一個「無光」的粉紅色形體。不是很複雜,是嗎? 在頂點著色器中,我們透過Three.js傳入了一些uniforms變數。有兩個4×4的矩陣uniforms變數:模型視圖矩陣和投影矩陣。你並不需要太了解這兩個矩陣是怎麼運作的。簡單地說,這兩個矩陣描述了三維點座標如何投影成為二維螢幕上的座標。
事實上,我只介紹了這兩段簡短的程式碼段。 Three.js在你自己的著色器程式碼前已經將它們加進來了,所以你不必擔心。實話說,Three.js還加了很多東西在你的程式碼前面,像是光照資料、節點顏色和節點法向量等等。如果沒有Three.js你要親自創建並設定這些對象,真的。 6.使用著色器材質
複製程式碼


程式碼如下:

/**
* 假設我們可以使用JQuery
* 將著色器的程式碼文字從DOM中抽取
*/
var vShader = $('vertexshader');
var fShader = $('fragmentshader');
var shaderMaterial =
new THREE.ShaderMaterial.Shader ({
vertexShader: vShader.text(),
fragmentShader: fShader.text()
});

從這兒開始,Three.js將會編譯並執行你的著色器,將其連結在你所創造的材質上,材質又依附在你所創造的mesh上。它並沒有變得比真的更容易。也許是這樣吧,但我們在考慮瀏覽器3D編程,我想你應該預期,這個主題是有一定複雜性的。
我們也可以像著色器材質加上另外兩種屬性:uniforms和attributes。他們可以是向量、整數或浮點數,但是如我之前所說,uniforms變數在計算所有點的過程中保持不變,所以它們更可能是單一的值,而attributes變數是對每個頂點而言的,所以他們應是數組。在一個mesh中,attribute變數和頂點應為一一對應的。
7.小結 這篇教程就到這裡了,實際上我已經講得很多了,但是在許多方面我都只是一掠而過。在下一篇教程中我會提供一個複雜的著色器,透過它我將傳入一些attributes變數和uniforms變數來做一些模擬光照效果。 我將這篇教學的源碼打包了,你可以下載下來作為參考
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn