搜尋
首頁web前端js教程THREE.JS入門教學(3)著色器-下_基礎知識

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

.簡介
這是WebGL著色器教程的後半部分,如果你沒看過前一篇,閱讀這篇教程可能會使你感到困惑,建議你翻閱前面的教學。

上一篇結束的時候,我們在螢幕中央畫了一個好看的粉紅色的球體。現在我要開始創造一些更有意思的東西了。

在這篇教學中,我們會先花點時間加入一個動畫循環,然後是頂點attributes變數和一個uniform變數。我們還要加一些varying變量,這樣頂點著色器就可以傳遞訊息到片元著色器了。最終的結果是哪個粉紅色的球體會從頂部開始向兩側“點燃”,然後作有規律的運動。這有一點迷幻,但是會幫助你對著色器中的三種變數有更好的了解:他們互相聯繫,實現了整個集合體。當然我們會在Three.js的框架中做這些事。
1.模擬光照
讓我們更新顏色吧,這樣球體看起來就不會是個扁平晦暗的圓了。如果我們想看看Three.js是怎麼處理光照的,我敢肯定你會發現這比我們需要的要複雜得多,所以我們先模擬光照吧。你應該瀏覽一下Three.js中那些奇妙的著色器,還有一些來自最近的一個 Chris Milk 和 Google, Rome 的WebGL專案。
回到著色器,我們要更新頂點著色器來傳遞頂點的法向量到片元著色器。利用一個varying變數:
複製程式碼 程式碼如下:

/// 建立一個變數,頂點著色器和片元著色器都包含了該變數
varying vec3 vNormal;
void main() {
// 將vNormal設為normal,後者是Three.js建立並傳遞給著色器的attribute變數
vNormal = normal;
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(position, 1.0);
}
vec4(position, 1.0);
}
複製程式碼 程式碼如下:

// 和頂點著色器中相同的變數vNormal
varying vec3 vNormal;
void main() {
// 定義光線向量
vec3 light = vec3(0.5,0.2,1.0);
// 確保其歸一化
light = normalize(light);
// 計算光線向量和法線向量的點積,如果點積小於0(即光線無法照到),就設為0
float dProd = max(0.0, dot(vNormal, light));
// 填充片元顏色
gl_FragColor = vec4(dProd, // R
dProd, // G
dProd, // B
1.0) ; // A
}

使用點積的原因是:兩個向量的點積顯示他們有多麼「相似」。如果兩個向量都是歸一化的,而且他們的方向一模一樣,點積的值就是1;如果兩個向量的方向剛好完全相反,點積的值就是-1。我們所做的就是把點積的值拿來作用到光纖上,所以如果這個點在球體的右上方,點積的值就是1,也就是完全照亮了;而在另一邊的點,得到的點積值接近0,甚至到了-1。我們將獲得的任何負值都設為0。當你將資料傳入之後,你會看到最基本的光照效果了。

下面是什麼?我們會將頂點的座標摻和進來。
2.Attribut變數
接下來我要透過Attribute變數為每個頂點傳遞一個隨機數,而這個隨機數用來將頂點沿著法線向量推出去一段距離。新的結果有點像是怪異的不規則物體,每次刷新頁面物體都會隨機變化。現在,他還不會動(後面我會讓他動起來),但是幾次刷新就可以很好地觀察到,他的形狀是隨機的。
讓我們開始為頂點著色器加入attribute變數:
複製程式碼 程式碼如下:

attribute float displacement;
varying vec3 vNormal;
void main() {
vNormal = normal;
// 將隨機數displacement轉換為三維向量,這樣就可以轉換為和維向量法線相乘了
vec3 newPosition = position
normal * vec3(displacement);
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(newPectionMatrix *

你看到什麼都沒變,因為attribute變數displacement還沒被設定你,所以著色器就使用了0作為預設值。這時displacement還沒起作用,但我們馬上就要在著色器材質中加上attribute變數了,然後Three.js就會自動地把它們綁在一起運行了。

同時也要注意這樣一個事實,我將更新後的位置指定給了一個新的三維向量變量,因為原來的位置變量position,就像所有的attribute變量一樣,都是只讀的。

3.更新著色器材質
現在我們來更新著色器材質,傳入一些東西給attribute物件displacement。記住,attribute物件是和頂點一一對應的,所以我們對球體的每一個頂點都有一個值,就像這樣:

複製程式碼 程式碼如下:
var attributes = {
displacement: {
type: 'f', // 浮點數
value: [] //空數組
}
};
var vShader = $('#vertexshader');
var fShader = $('#fragmentshader');
// 建立一個包含attribute屬性的著色器材質
var shaderMaterial =
new THREE.MeshShaderMaterial({
attributes: attributes,
vertexShader: vShader.text(),
fragmentShader: fragment: vShader.text(),
fragmentShader> );
// 填入displacement隨機數
var verts = sphere.geometry.vertices;
var values = attributes.displacement.value;
for(var v = 0; v values.push(Math.random() * 30);
}


這樣,就可以看到一個變形的球體了。最Cool的是:所有這些變形都是在GPU中完成的。

4.動起來
要讓這東西動起來,該怎麼做?好吧,應該要做這兩件事。 一個uniform變數amplitude,在每一幀控制displacement實際上造成了多少位移。我們可以使用正弦或餘弦函數來在每一幀中產生它,因為這兩個函數的取值範圍從-1到1。
一個幀循環。

我們需要將這個uniform變數加入著色器材質中,同時也需要加入頂點著色器。先來看看頂點著色器:


複製程式碼 程式碼如下:
uniform float amplitude; 🎜>attribute float displacement;
varying vec3 vNormal;
void main() {
vNormal = normal;
// 將displacement乘以amplitude,當我們在每一幀中都平滑改變amplitude ,畫面就動起來了
vec3 newPosition =
position
normal *
vec3(displacement *
amplitude);
gl_Position = projectionMatrix }


然後更新著色器材質:



複製程式碼
複製程式碼複製程式碼


複製程式碼



複製程式碼



複製程式碼



複製程式碼


複製程式碼



複製碼> 程式碼如下:} ; var vShader = $('#vertexshader'); var fShader = $('#fragmentshader'); // 建立最終的著色器材質var shaderMaterial = new THREE.MeshShaderMaterial({ uniforms: uniforms, attributes: attributes, vertexShader: vShader.text(), fragmentShader: fShader.text() ); 🎜> 我們的著色器也已經就緒了。但我們好像又倒退了一步,螢幕中又只剩下光滑的球了。別擔心,這是因為amplitude值設為0,因為我們將amplitude乘以了displacement,所以現在看不到任何變化。我們還沒設定循環呢,所以amplitude只可能是0. 在我們的JavaScript中,需要將渲染過程打包成一個函數,然後用requestAnimationFrame去呼叫函數。在這個函數裡,我們更新uniform(譯者註:即amplitude)的值。 複製程式碼 程式碼如下:

var frame = 0;
function update() {
// amplitude來自於frame的正弦值
uniforms.amplitude.value =
Math.sin(>uniforms.amplitude.value =
Math.sin(frame);
// 更新全域變數frame
frame = 0.1;
renderer.render(scene, camera);
// 指定下次螢幕刷新時,呼叫update
requestAnimFrame(update);
}
requestAnimFrame(update);

5.小結

就是它了!你看到球體正在奇怪地脈動著。關於著色器,還有太多的內容沒有講到呢,但是我希望這篇教學能夠對你有一些幫助。現在,當你看到一些其他的著色器時,我希望你能夠理解它們,而且你應該有信心創建自己的著色器了!
和往常一樣,我將這一課的源碼打包了
陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安裝JavaScript?如何安裝JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版