欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

THREE.JS入門教程(2)著色器-上

 更新時(shí)間:2013年01月24日 10:47:05   作者:  
Three.js是一個(gè)偉大的開源WebGL庫(kù),WebGL允許JavaScript操作GPU,在瀏覽器端實(shí)現(xiàn)真正意義的3D,本文將介紹頂點(diǎn)著色器/片元著色器/著色器變量等等,感興趣的朋友可以了解下哦
譯序
Three.js是一個(gè)偉大的開源WebGL庫(kù),WebGL允許JavaScript操作GPU,在瀏覽器端實(shí)現(xiàn)真正意義的3D。但是目前這項(xiàng)技術(shù)還處在發(fā)展階段,資料極為匱乏,愛好者學(xué)習(xí)基本要通過Demo源碼和Three.js本身的源碼來學(xué)習(xí)。

0.簡(jiǎn)介
之前我已經(jīng)給出了一篇《開始使用Three.js》。如果你還沒有讀過,你可能需要去讀一下,本文的基礎(chǔ)是在那一篇教程的基礎(chǔ)上完成的。

我想討論一下著色器。在Three.js幫助你免去了很多麻煩之前,原生WebGL就很優(yōu)秀了。有的時(shí)候,你也許會(huì)想要完成一些特定的效果,或者想對(duì)呈現(xiàn)在你的屏幕上的東西鉆研得更深入一些,那么著色器一定會(huì)進(jìn)入你的視野。如果你像我一樣,你也同樣希望實(shí)現(xiàn)一些比上一篇教程中的基礎(chǔ)更加有意思的東西。這篇教程中,我會(huì)講解Three.js的基礎(chǔ),這些基礎(chǔ)實(shí)際上為我們做了很多枯燥的工作。
在開始之前我還要說,這篇教程會(huì)有相當(dāng)多的篇幅在解釋著色器的代碼,之后會(huì)有一篇教程會(huì)在著色器代碼的基礎(chǔ)上前進(jìn)一點(diǎn),利用著色器去做點(diǎn)什么。這是因?yàn)橹鱯haders第一眼看上去并不易懂,需要一些解釋。
1.兩種著色器
WebGL沒有固定的渲染管線,你無法直接使用一個(gè)黑盒子式的著色器(譯者注:上個(gè)世紀(jì)的顯卡基本都只支持固定渲染管線);WebGL提供的是可編程的管線,這種方式更強(qiáng)大但也更難理解和使用。長(zhǎng)話短說,可編程渲染管線意味著編寫程序的人要自己負(fù)責(zé)獲取頂點(diǎn)并將它繪制在屏幕上了。著色器是渲染管線的一部分,有兩種著色器:
1.頂點(diǎn)著色器
2.片元著色器
你應(yīng)當(dāng)知道的是,這兩種著色器都完全運(yùn)行在顯卡的GPU上,我們將需要它們處理的數(shù)據(jù)從CPU上卸下,裝到GPU上,減輕了CPU的復(fù)旦。現(xiàn)代的GPU對(duì)著色器需要的調(diào)用的運(yùn)算類型都做了大幅優(yōu)化,這樣做很值得。
2.頂點(diǎn)著色器
基元形狀,比如一個(gè)球體,是由頂點(diǎn)構(gòu)成的,是吧?頂點(diǎn)著色器被依次傳入這些頂點(diǎn)中的一個(gè)頂點(diǎn),然后處理它。如何處理每個(gè)頂點(diǎn)是可以自由定制的,但頂點(diǎn)著色器有一個(gè)必做的事,就是為一個(gè)名為 gl_Position 的變量賦值,該變量是一個(gè)4維數(shù)組,表示該頂點(diǎn)最終在屏幕上的位置。這本身是個(gè)有意思的過程,因?yàn)槲覀儗?shí)際上在談?wù)撊绾螌⒁粋€(gè)三維坐標(biāo)(一個(gè)具有x、y、z值得頂點(diǎn))轉(zhuǎn)化為,或者說投影到二維的屏幕上。謝天謝地,要是我們使用Three.js之類的工具,我們能夠如此方便地訪問到 gl_Position 。
3.片元著色器
現(xiàn)在我們有包含頂點(diǎn)的三維物體了,現(xiàn)在要將物體投影到二維屏幕上了,但顏色哪里去了?紋理和光照呢?這正是片元著色器要處理的。
和頂點(diǎn)著色器類似,片元著色器有一項(xiàng)必須完成的任務(wù):設(shè)置或消除變量 gl_FragColor ,另一個(gè)四維浮點(diǎn)變量,也就是片元點(diǎn)最終的顏色。什么是片元?想象一個(gè)具有三個(gè)頂點(diǎn)的三角形,片元就是經(jīng)過這三個(gè)頂點(diǎn)計(jì)算后的,所有在三角形內(nèi)部的點(diǎn)。因此,片元值由頂點(diǎn)的值內(nèi)插生成。如果一個(gè)頂點(diǎn)的顏色是紅色,相鄰頂點(diǎn)的顏色是藍(lán)色,那么我們可以觀測(cè)到顏色從紅色頂點(diǎn)附近漸變,由紅色變成紫色,最終在藍(lán)色頂點(diǎn)附近變成藍(lán)色。
4.著色器變量
說到著色器變量,有三種:Uniforma,Attributes和Varyings。當(dāng)我第一次聽到這三個(gè)詞語(yǔ)時(shí),我很困惑,因?yàn)樗鼈兒臀抑坝玫降臇|西完全不匹配。但現(xiàn)在,你可以這樣理解它們:
1.Uniforms變量既可以傳入頂點(diǎn)著色器,也可以傳入片元著色器,它們包含了哪些在整個(gè)渲染過程中保持不變的變量,比如,一個(gè)點(diǎn)光源的位置。
2.Attributes變量對(duì)應(yīng)于每個(gè)頂點(diǎn),它們只可以傳入頂點(diǎn)著色器中,比如每個(gè)頂點(diǎn)都具有一個(gè)顏色。Attributes變量和頂點(diǎn)的關(guān)系是一一對(duì)應(yīng)的。
3.Varyings變量是在頂點(diǎn)著色器中定義,并且準(zhǔn)備傳入給片元著色器的變量。為了確保這點(diǎn),我們需要確保在兩個(gè)著色器中變量的類型和命名完全一致。一個(gè)經(jīng)典的應(yīng)用是法線向量,因?yàn)樵谟?jì)算光照的時(shí)候需要用到法線。
在后面一篇教程中,我會(huì)使用這三種變量,你也會(huì)學(xué)習(xí)到這三種變量如何真正應(yīng)用起來得。
現(xiàn)在,我們已經(jīng)談過了頂點(diǎn)著色器、片元著色器和三種著色器變量。是時(shí)候來看一個(gè)我們可以創(chuàng)建的最簡(jiǎn)單的著色器了。
5.Hello World(譯者吐槽:能不能不要秀法語(yǔ)?。?/STRONG>
這兒有一個(gè)最簡(jiǎn)單的頂點(diǎn)著色器:
復(fù)制代碼 代碼如下:

/**
* 每個(gè)頂點(diǎn)坐標(biāo)乘以模型視圖矩陣在乘以投影矩陣
* 獲得在二維屏幕上的坐標(biāo)
*/
void main() {
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(position,1.0);
}

一個(gè)最簡(jiǎn)單的片元著色器:
復(fù)制代碼 代碼如下:

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

這就是全部了。如果現(xiàn)在直接運(yùn)行的話,你就可以在屏幕上看到一個(gè)“無光”的粉紅色形體。不是很復(fù)雜,是嗎?

在頂點(diǎn)著色器中,我們通過Three.js傳入了一些uniforms變量。有兩個(gè)4×4的矩陣uniforms變量:模型視圖矩陣和投影矩陣。你并不需要太了解這兩個(gè)矩陣是怎么工作的。簡(jiǎn)單地說,這兩個(gè)矩陣描述了三維點(diǎn)坐標(biāo)如何投影成為二維屏幕上的坐標(biāo)。

事實(shí)上,我只介紹了這兩段簡(jiǎn)短的代碼段。Three.js在你自己的著色器代碼前已經(jīng)將它們加進(jìn)來了,所以你不必?fù)?dān)心。實(shí)話說,Three.js還加了很多東西在你的代碼前面,比如光照數(shù)據(jù)、節(jié)點(diǎn)顏色和節(jié)點(diǎn)法向量等等。如果沒有Three.js你要親自創(chuàng)建并設(shè)置這些對(duì)象,真的。
6.使用著色器材質(zhì)
復(fù)制代碼 代碼如下:

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

從這兒開始,Three.js將會(huì)編譯并運(yùn)行你的著色器,將其連接在你創(chuàng)建的材質(zhì)上,材質(zhì)又依附于你創(chuàng)建的mesh上。它并沒有變得比真的更容易。也許是這樣吧,但我們?cè)诳紤]瀏覽器3D編程,我想你應(yīng)該預(yù)期,這個(gè)話題是有一定復(fù)雜性的。

我們還可以像著色器材質(zhì)添加另外兩種屬性:uniforms和attributes。他們可以是向量、整數(shù)或者浮點(diǎn)數(shù),但是如我之前所說,uniforms變量在計(jì)算所有點(diǎn)的過程中保持不變,所以它們更加可能是單一的值,而attributes變量是對(duì)每個(gè)頂點(diǎn)而言的,所以他們應(yīng)當(dāng)是數(shù)組。在一個(gè)mesh中,attribute變量和頂點(diǎn)應(yīng)當(dāng)是一一對(duì)應(yīng)的。
7.小結(jié)
這篇教程就到這里了,實(shí)際上我已經(jīng)講得很多了,但是在許多方面我都只是一掠而過。在下一篇教程中我會(huì)提供一個(gè)復(fù)雜的著色器,通過它我將傳入一些attributes變量和uniforms變量來做一些模擬光照效果。
我將這篇教程的源碼打包了,你可以下載下來作為參考

相關(guān)文章

  • JavaScript中用于生成隨機(jī)數(shù)的Math.random()方法

    JavaScript中用于生成隨機(jī)數(shù)的Math.random()方法

    這篇文章主要介紹了JavaScript中用于生成隨機(jī)數(shù)的Math.random()方法,是JS入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-06-06
  • javascript模塊化是什么及其優(yōu)缺點(diǎn)介紹

    javascript模塊化是什么及其優(yōu)缺點(diǎn)介紹

    模塊化是一種將系統(tǒng)分離成獨(dú)立功能部分的方法,可將系統(tǒng)分割成獨(dú)立的功能部分,嚴(yán)格定義模塊接口、模塊間具有透明性
    2013-09-09
  • JavaScript reduce的基本用法詳解

    JavaScript reduce的基本用法詳解

    這篇文章主要為大家詳細(xì)介紹了JavaScript reduce的基本用法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • 全選復(fù)選框JavaScript編寫小結(jié)(附代碼)

    全選復(fù)選框JavaScript編寫小結(jié)(附代碼)

    這篇文章主要介紹了全選”復(fù)選框JavaScript編寫,分別附上html和js代碼以供大家更深刻了解,具體操作步驟大家可查看下文的詳細(xì)講解,感興趣的小伙伴們可以參考一下。
    2017-08-08
  • 了解重排與重繪

    了解重排與重繪

    重繪和重排操作都是代價(jià)昂貴的操作,它們會(huì)導(dǎo)致web應(yīng)用程序的UI反應(yīng)遲鈍,所以應(yīng)該盡可能減少這類過程的發(fā)生。下面我們來簡(jiǎn)單了解一下
    2019-05-05
  • JavaScript數(shù)據(jù)結(jié)構(gòu)與算法之鏈表

    JavaScript數(shù)據(jù)結(jié)構(gòu)與算法之鏈表

    鏈表就是線性表中針對(duì)順序存儲(chǔ)結(jié)構(gòu)的一種優(yōu)化手段,但是在javascript語(yǔ)言中由于數(shù)組的特殊性(自動(dòng)更新引用位置),所以我們可以采用對(duì)象的方式做鏈表存儲(chǔ)的結(jié)構(gòu)
    2016-01-01
  • Typescript中interface與type的相同點(diǎn)與不同點(diǎn)的詳細(xì)說明

    Typescript中interface與type的相同點(diǎn)與不同點(diǎn)的詳細(xì)說明

    這篇文章主要介紹了Typescript中interface與type的相同點(diǎn)與不同點(diǎn),并配有實(shí)例說明,需要的朋友可以參考下
    2022-11-11
  • 詳解JavaScript對(duì)W3C DOM模版的支持情況

    詳解JavaScript對(duì)W3C DOM模版的支持情況

    這篇文章主要介紹了詳解JavaScript對(duì)W3C DOM模版的支持情況,在JS前端編程的兼容性方面可作參考使用,需要的朋友可以參考下
    2015-06-06
  • javascript數(shù)組去重方法總結(jié)(推薦)

    javascript數(shù)組去重方法總結(jié)(推薦)

    這篇文章主要介紹了javascript數(shù)組去重方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • JavaScript中Math.SQRT2屬性的使用詳解

    JavaScript中Math.SQRT2屬性的使用詳解

    這篇文章主要介紹了JavaScript中Math.SQRT2屬性的使用詳解,是JS入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-06-06

最新評(píng)論