Three.js是一個很棒的開源WebGL函式庫,WebGL允許JavaScript操作GPU,在瀏覽器端實現真正意義的3D。但目前這項技術還在發展階段,資料極為匱乏,愛好者學習基本上要透過Demo源碼和Three.js本身的源碼來學習。
國外網站 aerotwist.com 有六篇較為簡單的入門教程,我嘗試著將其翻譯過來,與大家分享。
我在一些實驗專案中使用了Three.js,我發現它對快速上手瀏覽器3D程式設計確實很有幫助。透過Three.js,你不僅可以創建相機、物件、光線、材質等等,還可以選擇著色器,可以決定使用何種技術(WebGL、Canvas或SVG)在網頁上渲染你的3D圖形。 Three.js是開源的,你甚至可以參與這個專案。但現在,我將把重點放在基礎的介紹上,我將向你展示如何使用這個引擎。
儘管Three.js如此奇妙,但有時候它也會令人抓狂。例如,你將花費大量時間閱讀例程,做一些逆向工程(在我的情況下)來確定某個函數的作用,有時還要去GitHub上提問。如果你需要提問,Mr. doob和AlteredQualia是極好的選擇。
1.基礎
我假定你的三維圖形學知識過關,而且也在一定程度上掌握了JavaScript。如果不是這樣,那先去學一點吧,否則直接看這篇教程,也許會感到困惑。
在我們的三維世界裡,我們有以下這些東西。我會帶你一步一步創建它們。
1.場景
2.渲染器
3.相機
4.物體(有材質的)
當然,你也可以創造些其他的東西,我也希望你如此做。
2.瀏覽器支援
簡單地看一下瀏覽器的支援情況吧。 Google家的Chrome瀏覽器支援Three.js,在我的實驗裡,無論是對渲染器的支援程度還是JavaScript解釋器的運行速度,Chrome都是做得最好的:它支援Canvas、WebGL和SVG,而且運行得非常快。 FireFox瀏覽器排在第二位,它的JavaScript引擎的速度比Chrome慢了半拍,但是對渲染器的支援也很棒,而且FireFox的速度,隨著版本更新也越來越快。 Opera瀏覽器正在逐漸增加對WebGL的支持,Mac上的Safari瀏覽器有一個開啟WebGL的選項。整體上,這兩個瀏覽器僅支援Canvas渲染。微軟家的IE9現在只支援Canvas渲染,而且微軟似乎不樂意支援WebGL這個新特性,所以我們現在絕對不會用IE9來做實驗。
3.設定場景
假設你已經選擇了一個支援所有渲染技術的瀏覽器,而且你準備好透過Canvas或WebGL來渲染場景(這是更標準化的選擇)。 Canvas比WebGL有著更廣泛地支持,但是WebGL可以直接在GPU上操作,這意味著你的CPU可以專注地處理非渲染類別的工作,例如實體引擎或與使用者互動等。
無論你選擇何種渲染器,你都必須牢記在心的是:JavaScript程式碼需要最佳化。三維顯示對瀏覽器來說不是一項輕鬆的工作(現在能夠這樣做就很偉大了),所以如果你的渲染太慢了,你需要知道你代碼的瓶頸在何處,如果可能,改善它。
說了這麼多,我想你已經下載好Three.js原始碼,而且將它引入了你的html文檔了。那麼如何開始創建一個場景呢?如此:
// 設定場景大小
var WIDTH = 400,
HEIGHT = 300;
// 設定一些相機參數
var VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
10000;
// 取得DOM結構中的元素
// - 假設我們使用了JQuery
var $container = $('#container');
// 建立渲染器、相機和場景
var renderer = new THREE.WebGLRenderer();
var camera =
new THREE.PerspectiveCamera(
VIEW_ANGLE,
ASPECT,
NEAR,NEAR>NEAR. 🎜>var scene = new THREE.Scene();
// 將相機加入場景
scene.add(camera);
// 相機的初始位置為原點
// 將相機拉回來一些(譯者註:這樣才能看到原點)
camera.position.z = 300;
// 啟動渲染器
renderer.setSize(WIDTH, HEIGHT);
// 將渲染器加到DOM結構中
$container.append(renderer.domElement);
你看,簡單吧!
4.建立網格表面 現在我們有了一個場景,一個相機和一個渲染器(在我的例子裡,當然是一個WebGL渲染器),但我們事實上什麼還沒畫呢。事實上,Three.js提供了載入某幾種標準格式3D檔案的支持,如果你在Blender,Maya,Cinema4D或是什麼其他工具中建模,這簡直太棒了。為了簡單(畢竟這才剛開始呢!)我們先來考慮基元。基元就是基本的幾何表面,例如最基本的球體、平面、立方體、圓柱體。利用Three.js可以很方便地建立這些基元:
程式碼如下:
// 設定球體參數(譯者註:球體被劃分為16×16的網格,如果後兩個參數取4、2,則產生一個八面體,請想像)
var radius = 50,
segments = 16,
rings = 16;
// material覆蓋在geometry上,產生mesh
var sphere = new THREE.Mesh(
new THREE.SphereGe7>
segments,
rings),
sphereMaterial);
// 將mesh加入場景
scene.add(sphere);
好了,但是球體上的材質呢?在程式碼中我們使用了一個sphereMaterial變量,我們還沒定義它。那我們就先來看看怎麼創建材質吧。
5.材質
毫無疑問,這是Three.js最有用的部分了。這部分提供了幾個非常容易使用的通用材質模型:
1.Basic材質:表示一種不考慮光照的材質,現在只能這麼說了。
2.Lambert材質:(譯者註:朗伯面,各向同性反射)。
3.Phong材質:(譯者註:馮氏面,有光澤的表面,介於鏡面反射和朗伯反射之間的反射,描述真實世界的反射)。
除此之外,還有一些其他類型材質,簡單起見,就留給你自己探索。事實上,使用WebGL類型的渲染器時,材質實在太好用了。為什麼呢?因為在原生WebGL種你必須親自為每個渲染編寫著色器,而著色器本身就是個巨大的工程:簡單地說著色器是使用GLSL語言(OpenGL的著色器語言)寫的,用來操作GPU的程序,這意味著你要在數學上模擬光照,反射等等,這很快就變成一項極為複雜的工作。多虧有了Three.js你才可以不必去自己寫著色器,當然,如果你想親自寫的話,你可以使用MeshShaderMaterial,可見這是很靈活的設定。
現在,讓我們用朗伯面材質覆蓋球體:
複製程式碼
複製程式碼
程式碼
// 創建球體表面的材質
var sphereMaterial =
new THREE.MeshLambertMaterial( {
color: 0xCC0000
}
複製程式碼
程式碼如下:
// 建立一個點光源
var pointLight =
new THREE.PointLight(0xFFFFFF);
// 設定點光源的位置
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130; // 將點光源加入場景
scene.add(pointLight);
複製程式碼
程式碼如下: // 畫! renderer.render(scene, camera);
你很可能像多次渲染,而不是只渲染一次,所以如果你要去做一個循環,你應該使用requestAnimationFrame。這是目前最好的,在瀏覽器中處理動畫的方法,雖然還沒有得到最全面的支持,但我強烈建議你去看一看Paul Irish的博客。
8.通用的物件屬性 如果你花點時間去瀏覽一次Three.js的原始碼,你會發現很多物件都繼承自Object3D。這個基類包含了許多有用的屬性,例如位置、旋轉和縮放的資訊。特別的,我們的球體是一個Mesh對象,而Mesh物件繼承自Object3D對象,但又增加了些自己的屬性:geometry和material。為什麼要說這些?因為你一定不會只滿足於螢幕中一個什麼都不做的圓球,而這些(譯者註:基類中的)屬性允許你操作Mesh物件更底層的細節和各種各樣的材質。
// sphere是mesh物件
// sphere是個mesh物件
sphere. geometry
// sphere包含了一些點和麵的資訊
sphere.geometry.vertices // 一個陣列
sphere.geometry.faces // 另一個陣列
// mesh物件繼承自object3dometry.faces // 另一個陣列
// mesh物件繼承自object3d物件
sphere.position // 包含x,y,z
sphere.rotation // 同上
sphere.scale // ... 同上 複製程式碼
程式碼如下:
// 設定geometry為動態的,這樣才允許改變其中的頂點
sphere.geometry.dynamic = true;
// 告訴Three>// 告訴Three .js,需要重新計算頂點
sphere.geometry.__dirtyVertices = true;
// 告訴Three.js,需要重新計算頂點
sphere.geometry.__dirtyNormals = true;
還有更多的標識,但我發現這兩個是最有用的。你應該只是標識那些確實需要即時計算的屬性來避免無謂的運算開銷。
10.小結
我希望這篇簡單的介紹對你有幫助。沒什麼能比得上捲起袖子親手實踐了,我強烈建議你這麼做。在瀏覽器裡面運行3D程式很有意思,而且使用像Three.js這樣一個引擎免去了很多麻煩,讓你一開始就能專注於那些真正cool的事情。 我將這篇教學的源碼打包了,你可以下載下來作為一份參考。