THREE.JS入門教程(3)著色器-下
2024-05-06 14:19:51
供稿:網友
譯序
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變量vNormal,頂點著色器和片元著色器都包含了該變量
varying vec3 vNormal;
void main() {
// 將vNormal設置為normal,后者是Three.js創建并傳遞給著色器的attribute變量
vNormal = normal;
gl_Position = projectionMatrix *
modelViewMatrix *
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。當你將數據傳入之后,你就會看到最基本的光照效果了。