Three.js 入門:如何使用並繪製基礎 3D 圖形
一、 前言
Three.js 是一款 webGL(3D繪圖標準,在此不贅述)引擎,可以運行於所有支持 webGL 的瀏覽器。Three.js 封裝了 webGL 底層的 API ,為我們提供了高級的開發介面,可以使用簡單的代碼去實現 3D 渲染。(官網:https://threejs.org/)
Jason 豈安科技前端研發工程師
三年互聯網前端開發經驗,曾參與過多個系統框架的搭建和組件開發,負責豈安科技產品的數據可視化和公用組件開發。更多乾貨內容關注微信公眾號:bigsec
二、 為什麼要選擇Three.js?
Three.js 作為原生 web3D 引擎,對插件式 web3D 引擎的優勢不言而喻:不需要安裝插件、在移動端支持好。
Three.js 與其他原生 web3D 引擎對比:
- Babylon.js:一個強大的 3D 遊戲引擎,由 Microsoft 的員工 David Cathue 主導開發。和 Three.js 相比,three.js 更傾向於動畫,而 Babylon.js 則更適合遊戲開發。
- PhiloGL:增加了額外的功能幫助你可以使用本地的 WebGL ,這個 WebGL 的介面不是百分之百的被封裝好了的,這使得 PhiloGL 上手難度較高。
- SceneJS:一個開源的 JavaScript 3D 引擎,特別適合需要高精度細節的模型需求,比如工程學和醫學上常用的高精度模型。
- CopperLicht:一個「商業級別的 WebGL 3D 引擎和編輯器」,你可以免費使用,但是要想獲得未壓縮的完整版帶支持文檔的源碼和其他服務,則需要購買授權。
相對這些 web3D 引擎,Three.js 的還有以下幾點優勢:
- 開發和維護比較活躍;
- 文檔齊全,案例豐富,易於學習;
- 設計靈活、方便拓展以及增加新的特性;
- 我們可以根據自己的需要去選擇web3D引擎。
三、 開始Three.js
1、 引導
在開始我們的第一個 3D 程序之前,我們需要了解 Three.js 的一些基礎,以下是 Three.js 製作 3D 的五要素:
a. 渲染器(render)
我們可以把渲染器想想成為一個畫布,我們需要在這個畫布上去畫出我們需要展示的東西。
b. 場景(scene)
相當於一個空間,我們需要將展示的東西放在這個空間里,然後再在畫布上繪製出來。
c. 照相機(camera)
相當於眼睛,我們想要看到物體,就需要眼睛去看。
d. 光源(light)
物體需要光照才能看見,不然就是漆黑一片(但是在某些情況下展示物體不需要光源)。
e. 物體(object)
我們想要表現的內容,會有形狀和材質屬性。
了解了五要素之後,就可以開始寫我們的代碼了。
2、 創建渲染器
首先,我們創建一個渲染器。創建渲染器有兩種方式:
a. 在 html 上寫出 canvas 元素
<canvas id="mainCanvas" width_="600px" height="450px" ></canvas>然後創建渲染器時綁定此元素var renderer = new THREE.WebGLRenderer({ canvas: document.getElementById(mainCanvas) }); renderer.setClearColor(「#000」); // 設置渲染器背景為黑色
b. html 上不創建 canvas 元素,而是使用普通的元素作為容器
<div id="mainCanvas" stylex="width:600px;height:450px;" ></div>
然後創建渲染器,放入容器中
var canvasContainer = document.getElementById(mainCanvas); var width = canvasContainer.clientWidth; //獲取畫布的寬 var height = canvasContainer.clientHeight; //獲取畫布的高 var renderer = new THREE.WebGLRenderer({ antialias: true //抗鋸齒開 }); renderer.setSize(width, height); //設置渲染器的寬和高 renderer.setClearColor(0x000000); //設置渲染器的背景顏色為黑色 var canvas = renderer.domElement; //獲取渲染器的畫布元素 canvasContainer.appendChild(canvas); //將畫布寫入html元素中
這樣,我們的渲染器就創建成功了。
創建渲染器時,還可以設置多個屬性,比如抗鋸齒、透明度等等,詳見 three.js 官方文檔。
3、 創建場景
渲染器創建之後,我們再創建場景,準備將我們需要繪製的東西放入場景。
var scene = new THREE.Scene();
4、 創建照相機
照相機常用的有兩種,一種叫正投影相機:
THREE.OrthographicCamera(left,right,top,bottom,near,far);
下圖為該照相機的視野:
一種叫做透視照相機:
THREE.PerspectiveCamera( fov, aspect, near, far ) ;
下圖為該照相機的視野:
下圖為兩個照相機展示效果的對比:
- 左邊為正投照相機,遠近大小都一樣;
- 右邊為透視照相機,遠小近大,更接近於人眼觀察物體的感覺。
在此以正投照相舉例:
var camera = new THREE.OrthographicCamera(-6, 6, 4.5, -4.5, 0, 50); //創建照相機 camera.position.set(35, 15, 25); //設置照相機的位置 camera.lookAt(new THREE.Vector3(0, 0, 0)); //設置照相機面向(0,0,0)坐標觀察照相機默認坐標為(0,0,0);默認面向為沿z軸向里觀察;
5、 創建光源
常用光源有:
a. 平行光(DirectionalLight),效果類似太陽光
DirectionalLight ( color, intensity )
color — 光源顏色的RBG數值。
intensity — 光強的數值。
b. 點光源(PointLight),效果類似燈泡
PointLight ( color, intensity, distance, decay )
color — 光源顏色的RBG數值。
intensity — 光強的數值。
distance -- 光強為0處到光源的距離,0表示無窮大。
decay -- 沿著光照距離的衰退量。
c. 聚光光源(SpotLight),效果類似聚光燈
SpotLight ( color, intensity, distance, angle, penumbra, decay )
color — 光源顏色的RBG數值。
intensity — 光強的數值。
distance -- 光強為0處到光源的距離,0表示無窮大。
angle -- 光線散射角度,最大為Math.PI/2。
penumbra -- 聚光錐的半影衰減百分比。在0和1之間的值。默認為0。
decay -- 沿著光照距離的衰退量。
在此以點光源舉例:
var light = new THREE.PointLight(0xffffff, 1, 100); //創建光源light.position.set(12, 15, 10); //設置光源的位置 scene.add(light); //在場景中添加光源
6、 創建物體
製作物體的方法是 Mesh:
new THREE.Mesh(Geometry, Material);
Geometry 為物體的形狀,Material 為物體的材質;
a. 形狀(Geometry)
three.js 給出了很多方法去生成固定的形狀,比如長方體(BoxGeometry)、球體(SphereGeometry)、圓形(CircleGeometry)等等。還有根據坐標去生成具體形狀的方法,可以藉助第三方建模軟體建模之後引入,轉換為坐標後再生成,就可以做比較複雜的形狀了,比如人臉、汽車等等。
在此以長方體為例生成形狀:
//設置正方體寬度,高度,深度分別為5,5,5
var geometry = new THREE.BoxGeometry (5, 5, 5);
b. 材質(Material)
材質就像是物體的皮膚,決定物體外表的樣子,例如物體的顏色,看起來是否光滑,是否有貼圖等等。
常用材質有:
- 網格基礎材質(MeshBasicMaterial)
該材質不受光照的影響,不需要光源即可顯示出來,設置顏色後,各個面都是同一個顏色。
- 網格法向材質(MeshNormalMaterial)
該材質不受光照的影響,不需要光源即可顯示出來,並且每個方向的面的顏色都不同,同但一個方向的面顏色是相同的,該材質一般用於調試。
- 網格朗博材質(MeshLambertMaterial)
該材質會受到光照的影響,沒有光源時不會顯示出來,用於創建表面暗淡,不光亮的物體。
- 網格 Phong 材質(MeshPhongMaterial)
該材質會受到光照的影響,沒有光源時不會顯示出來,用於創建光亮的物體。
在此以網格 Phong 材質為例創建材質:
var material = new THREE.MeshPhongMaterial({ color: "yellow" //設置顏色為yellow});創建形狀和材質之後,就可以創建該物體了://創建物體var cube = new THREE.Mesh(geometry, material);
7、 渲染畫布
通過以上步驟,我們已經有了渲染器(renderer)、場景(scene)、照相機(camera)、光源(light)和物體(cube),此時我們需要將光源和物體加入場景中:
scene.add(light);scene.add(cube);
然後再使用渲染器將場景和照相機渲染出來:
renderer.render(scene, camera);
效果如下圖:
四、 結束語
在以上內容中,只寫到了 Three.js 中提供的基礎功能,還有很多高級的功能需要大家去探索。希望大家看完這篇文章後能對 Three.js 有一個初步的了解,並能夠使用 Three.js 繪製出基礎的 3D 圖形。
大家可以去 Three.js 官網的 examples 中看看,這裡面都是一些很優秀和典型的 examples,並且還有代碼可以下載,大家可以去研究探索一番。
在此附上幾個精彩的例子供大家欣賞:
推薦閱讀: