中文原文鏈接:http://www.21haolou.com/articles/show/140
英文原文鏈接:http://aerotwist.com/tutorials/getting-started-with-three-js/
Three.js的GitHub:https://github.com/mrdoob/three.js/
Three.js的官方演示站:http://mrdoob.github.com/three.js/(很酷炫的實例)
Three.js在處理瀏覽器3D效果方面表現優異。通過Three js,你可以創建鏡頭,物體,光線,材質等。
介紹
我在自己的一些實驗性項目中運用了Three.js,它在處理瀏覽器3D效果方面表現優異。通過Three js,你可以創建鏡頭(Cameras),物體(objects),光線(lights),材質(materials)等等,你還可以選擇渲染器:可以使用HTML5的Canvas來繪制場景,也可選擇使用WebGL或是SVG來渲染。另外它還是開源的,因而若有興趣的話,你也可參與到Three js項目中來。不過,這里主要是講講我自己從使用該3D引擎中學到的一些東西,並介紹一些基本內容。
盡管Three js有種種好處,但是你也可能不時會碰到糾結之處。一個典型的情況就是你需要耗費大量時間研究他人實例,做逆向工程,搜尋具體的函數,偶爾還需通過GitHub需求幫助。順便提一下,如果你的確需要尋求幫助,Mr. doob 和 AlteredQualia這兩個地方會幫上你大忙的。
基礎
這里,我默認讀者已經了解基本的3D概念,並具精通JavaScript技能。如果你沒有上述基礎,我建議你在接觸Three js之前最好學習一下,不然后面你會碰到些疑惑的。
在3D世界中,我們會涉及到下面這些概念,這些概念會伴隨整個創作流程:
- 場景
- 渲染器
- 鏡頭
- 物體(帶材質的)
當然,你可以制作一些瘋狂的內容,而且我也希望這樣干,並且在你自己的瀏覽器中開始實驗。
兼容性
對於瀏覽器的支持情況,我在這里做一個快速簡要說明。以我的經歷來看,在對渲軟引擎的支持及其JavaScript引擎的速度方面,Google的Chrome瀏覽器做的最好。Chrome支持Canvas,WebGL以及SVG,且速度極快。Firefox的表現位居第二,其JavaScript引擎速度要比Chrome稍許慢些,但是對渲軟器的支持依舊不錯,而且新版本JavaScript引擎速度越來越快。Opera還正在增加對WebGL的支持,而Mac上的Safari瀏覽器提供了啟用WebGL的選項。因此,基本上Opera和Safar只支持Canvas渲軟,了解這點很重要。目前IE9也只支持Canvas渲染,而且我也尚未聽說微軟有任何支持WebGL的消息。在目前階段,微軟似乎不會考慮WebGL。
設置場景
這里我假設你選用了支持所有渲染引擎的瀏覽器,你希望使用Canvas或是WebGL來渲染,因為這兩個是更為標准的技術。Canvas得到的支持程度要好於WebGL,這里值得一提的是,WebGL是調用的顯卡的GPU,這樣CPU的話就主要負責其他非渲染類的任務,像物理引擎或用戶交互方面的任務。
不管你選用何種引擎,你應牢記JavasScript需要為性能優化,畢竟對瀏覽器而言,3D運算不是項輕松的內容(能實現就已經很牛B了)。因此需要清楚的了解自身代碼的瓶頸之處,如有可能,消滅這些瓶頸代碼。
假設你已經下載並將three js包含在你的HTML文件中,那么我們如何設置場景(scene)呢?見下面例子
// 設置場景大小 var WIDTH = 400, HEIGHT = 300; // 設置鏡頭屬性 var VIEW_ANGLE = 45, ASPECT = WIDTH / HEIGHT, NEAR = 0.1, FAR = 10000; // 獲取綁定的DOM元素,假設我們使用的jQuery處理。 var $container = $('#container'); // 創建WebGL渲染器,鏡頭以及場景 var renderer = new THREE.WebGLRenderer(); var camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR); var scene = new THREE.Scene(); // 在場景中添加鏡頭 scene.add(camera); // 鏡頭起始位置0,0,0,因此將鏡頭回拉 camera.position.z = 300; // 開始渲染 renderer.setSize(WIDTH, HEIGHT); //增添渲染器提供的DOM元素 $container.append(renderer.domElement);
創建網格曲面
現在創建好一個場景,一個鏡頭以及一個渲染器(在上述示例中,我選用WebGL做渲染),但是我們還尚未繪制任何內容。Three js實際上還支持部分不同標准的文件類型。如果你有模型需要從Blender,Maya或是Cinema4D導入的,這點特性就顯得非常不錯。為了簡單起見,我講講基本物體(primitive)。基本物體是幾何網格曲面,或是像球體,平面,立方體和圓柱體這類相對簡單的物體。Three js可以讓你輕松地創建上述類型的基本物體。
//設置球體變量 var radius = 50, segments = 16, rings = 16; // 使用球體幾何創建新的網格曲面,接下來我會覆蓋上球體材質。 var sphere = new THREE.Mesh( new THREE.SphereGeometry( radius, segments, rings), sphereMaterial); // 在場景中添加球體。 scene.add(sphere);
嗯,一切完好,但是球體的材質如何添加呢?在代碼中,我們使用了球體材質的變量(sphereMaterial),但是尚未定義,接下來,我們需要更詳細的了解下材質方面的內容。
材質
毋庸置疑,這部分內容是Three js最有用的部分。它提供了不少常見(而且非常方便)的材質可覆蓋於網格曲面上
- "基本"材質 ——在無光情況下進行渲染
- Lambert材質
- Phong材質
除此之外還有其他材質,但是為簡單起見,讀者可自行摸索。在WebGL中,這些材質可是救命的功能。為什么呢?因為在WebGL中,你必須得為所有需要渲染的東西編寫着色器(Shader),而着色器本身就是一個龐雜的話題,簡單說來,着色器使用GLSL(OpenGL Shader Language)寫成。它告訴GPU如何渲染物體的外觀。這意味着你需要對光線,反射等等進行模擬。其內容會變得極為復雜。幸虧有了Three js,你不用處理這部分內容。但如果你想自己編寫着色器的話,那么你也可以用MeshShaderMaterial來實現,因此它的設置相對靈活。
接下來,我們可對球體運用lambert材質
// 創建球體的材質 var sphereMaterial =new THREE.MeshLambertMaterial({ color: 0xCC0000 });
這里值得一提是,除了顏色,你在創建材質時還可以指定其他屬性,比如,順滑度或環境貼圖。對於引擎提供的其他物體以及材質的可設置屬性選項,你可以訪問這個維基頁面查看。
光線
如果你現在就開始渲染場景的話,你只會看到一個紅色的圓。雖然我們已經添加了Lambert材質,但是場景中默認是沒有光源的。Three js就會歸位為全環境光,其等同於表面顏色。我們可以指定一點光源來解決這個問題。
// 創建點光源 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這篇內容。
一般物體的屬性
如果你有時間閱讀Three js的代碼,你會發現許多物體繼承自Object3D。這一以及基本的對象,包含一些非常有用的屬性,比如位置, 旋度,縮放比例等信息。我們的球體就是一個繼承自Object3D的網格曲面,不過它增添了自身特有的一些屬性:幾何及材質。為什么我要提這些呢?你不可能只想在屏幕上顯示一個啥都不能干的球體。這些屬性非常值得研究,因為它可以讓你隨時操控網格曲面的細節之處。
// 球形幾何體 sphere.geometry // 包含的頂點及面。 sphere.geometry.vertices // 一個數組 sphere.geometry.faces // 也是一個數組 // 位置 sphere.position // 包含X,Y,Z sphere.rotation // 同上 sphere.scale // 同上
小提示
使用Three js時,有一點需要了解:如果你修改網格曲面的頂點時,你注意到在循環渲染中,並沒有發生任何變化。為什么?原因就是Three js為了優化性能起見,對網格曲面的數據進行了緩存。這時你需要告訴three js,內容已經發生改動,以便three js重新進行計算。如下:
// 將幾何體設置為動態,允許更新 sphere.geometry.dynamic = true; // 對頂點的改動 sphere.geometry.__dirtyVertices = true; // 對法線(normals)的改動 sphere.geometry.__dirtyNormals = true;
使用Three js需要注意的不止這點,但是我發現這點最需要注意,你應只標記已做改動的內容,避免無謂的計算。
結論
這里,我希望這篇對three js的簡單入門介紹能夠幫你。實踐出真知,我強烈建議你動手實踐。在瀏覽器中跑3D樂趣不少,而使用three js這樣的引擎可為你免掉不少麻煩,使你專注於創造。
為了方便起見,我將這篇文章中涉及的源代碼壓縮打包了,供你參考。
原文:http://aerotwist.com/tutorials/getting-started-with-three-js/