Three.js的使用及繪制基礎(chǔ)3D圖形詳解
一、 前言
Three.js 是一款 webGL(3D繪圖標(biāo)準(zhǔn),在此不贅述)引擎,可以運(yùn)行于所有支持 webGL 的瀏覽器。Three.js 封裝了 webGL 底層的 API ,為我們提供了高級(jí)的開(kāi)發(fā)接口,可以使用簡(jiǎn)單的代碼去實(shí)現(xiàn) 3D 渲染。(官網(wǎng):https://threejs.org/)
二、 為什么要選擇Three.js?
Three.js 作為原生 web3D 引擎,對(duì)插件式 web3D 引擎的優(yōu)勢(shì)不言而喻:不需要安裝插件、在移動(dòng)端支持好。
Three.js 與其他原生 web3D 引擎對(duì)比:
- Babylon.js:一個(gè)強(qiáng)大的 3D 游戲引擎,由 Microsoft 的員工 David Cathue 主導(dǎo)開(kāi)發(fā)。和 Three.js 相比,three.js 更傾向于動(dòng)畫(huà),而 Babylon.js 則更適合游戲開(kāi)發(fā)。
- PhiloGL:增加了額外的功能幫助你可以使用本地的 WebGL ,這個(gè) WebGL 的接口不是百分之百的被封裝好了的,這使得 PhiloGL 上手難度較高。
- SceneJS:一個(gè)開(kāi)源的 JavaScript 3D 引擎,特別適合需要高精度細(xì)節(jié)的模型需求,比如工程學(xué)和醫(yī)學(xué)上常用的高精度模型。
- CopperLicht:一個(gè)“商業(yè)級(jí)別的 WebGL 3D 引擎和編輯器”,你可以免費(fèi)使用,但是要想獲得未壓縮的完整版帶支持文檔的源碼和其他服務(wù),則需要購(gòu)買(mǎi)授權(quán)。
相對(duì)這些 web3D 引擎,Three.js 的還有以下幾點(diǎn)優(yōu)勢(shì):
- 開(kāi)發(fā)和維護(hù)比較活躍;
- 文檔齊全,案例豐富,易于學(xué)習(xí);
- 設(shè)計(jì)靈活、方便拓展以及增加新的特性;
我們可以根據(jù)自己的需要去選擇web3D引擎。
三、 開(kāi)始Three.js
1、 引導(dǎo)
在開(kāi)始我們的第一個(gè) 3D 程序之前,我們需要了解 Three.js 的一些基礎(chǔ),以下是 Three.js 制作 3D 的五要素:
1、渲染器(render)
我們可以把渲染器想想成為一個(gè)畫(huà)布,我們需要在這個(gè)畫(huà)布上去畫(huà)出我們需要展示的東西。
2、場(chǎng)景(scene)
相當(dāng)于一個(gè)空間,我們需要將展示的東西放在這個(gè)空間里,然后再在畫(huà)布上繪制出來(lái)。
3、照相機(jī)(camera)
相當(dāng)于眼睛,我們想要看到物體,就需要眼睛去看。
4、光源(light)
物體需要光照才能看見(jiàn),不然就是漆黑一片(但是在某些情況下展示物體不需要光源)。
5、物體(object)
我們想要表現(xiàn)的內(nèi)容,會(huì)有形狀和材質(zhì)屬性。
了解了五要素之后,就可以開(kāi)始寫(xiě)我們的代碼了。
2、 創(chuàng)建渲染器
首先,我們創(chuàng)建一個(gè)渲染器。創(chuàng)建渲染器有兩種方式:
a. 在 html 上寫(xiě)出 canvas 元素
<canvas id="mainCanvas" width="600px" height="450px" ></canvas>
然后創(chuàng)建渲染器時(shí)綁定此元素
var renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('mainCanvas')
});
renderer.setClearColor(“#000”); // 設(shè)置渲染器背景為黑色
b. html 上不創(chuàng)建 canvas 元素,而是使用普通的元素作為容器
<div id="mainCanvas" style="width:600px;height:450px;" ></div>
然后創(chuàng)建渲染器,放入容器中
var canvasContainer = document.getElementById('mainCanvas');
var width = canvasContainer.clientWidth; //獲取畫(huà)布的寬
var height = canvasContainer.clientHeight; //獲取畫(huà)布的高
var renderer = new THREE.WebGLRenderer({
antialias: true //抗鋸齒開(kāi)
});
renderer.setSize(width, height); //設(shè)置渲染器的寬和高
renderer.setClearColor(0x000000); //設(shè)置渲染器的背景顏色為黑色
var canvas = renderer.domElement; //獲取渲染器的畫(huà)布元素
canvasContainer.appendChild(canvas); //將畫(huà)布寫(xiě)入html元素中
這樣,我們的渲染器就創(chuàng)建成功了。創(chuàng)建渲染器時(shí),還可以設(shè)置多個(gè)屬性,比如抗鋸齒、透明度等等,詳見(jiàn) three.js 官方文檔。
3、 創(chuàng)建場(chǎng)景
渲染器創(chuàng)建之后,我們?cè)賱?chuàng)建場(chǎng)景,準(zhǔn)備將我們需要繪制的東西放入場(chǎng)景。
var scene = new THREE.Scene();
4、 創(chuàng)建照相機(jī)
照相機(jī)常用的有兩種,一種叫正投影相機(jī):
THREE.OrthographicCamera( left, right, top, bottom, near, far );
下圖為該照相機(jī)的視野:

一種叫做透視照相機(jī):
THREE.PerspectiveCamera( fov, aspect, near, far ) ;
下圖為該照相機(jī)的視野:

下圖為兩個(gè)照相機(jī)展示效果的對(duì)比:

**左邊為正投照相機(jī),遠(yuǎn)近大小都一樣;右邊為透視照相機(jī),遠(yuǎn)小近大,更接近于人眼觀(guān)察物體的感覺(jué)。**
在此以正投照相舉例:
var camera = new THREE.OrthographicCamera(-6, 6, 4.5, -4.5, 0, 50); //創(chuàng)建照相機(jī) camera.position.set(35, 15, 25); //設(shè)置照相機(jī)的位置 camera.lookAt(new THREE.Vector3(0, 0, 0)); //設(shè)置照相機(jī)面向(0,0,0)坐標(biāo)觀(guān)察
照相機(jī)默認(rèn)坐標(biāo)為(0,0,0);
默認(rèn)面向?yàn)檠貁軸向里觀(guān)察;
5、 創(chuàng)建光源
常用光源有:
1、平行光(DirectionalLight),效果類(lèi)似太陽(yáng)光
DirectionalLight ( color, intensity )
color — 光源顏色的RBG數(shù)值。
intensity — 光強(qiáng)的數(shù)值。
2、點(diǎn)光源(PointLight),效果類(lèi)似燈泡
PointLight ( color, intensity, distance, decay )
color — 光源顏色的RBG數(shù)值。
intensity — 光強(qiáng)的數(shù)值。
distance -- 光強(qiáng)為0處到光源的距離,0表示無(wú)窮大。
decay -- 沿著光照距離的衰退量。
3、聚光光源(SpotLight),效果類(lèi)似聚光燈
SpotLight ( color, intensity, distance, angle, penumbra, decay )
color — 光源顏色的RBG數(shù)值。
intensity — 光強(qiáng)的數(shù)值。
distance -- 光強(qiáng)為0處到光源的距離,0表示無(wú)窮大。
angle -- 光線(xiàn)散射角度,最大為Math.PI/2。
penumbra -- 聚光錐的半影衰減百分比。在0和1之間的值。默認(rèn)為0。
decay -- 沿著光照距離的衰退量。
在此以點(diǎn)光源舉例:
var light = new THREE.PointLight(0xffffff, 1, 100); //創(chuàng)建光源 light.position.set(12, 15, 10); //設(shè)置光源的位置 scene.add(light); //在場(chǎng)景中添加光源
6、 創(chuàng)建物體
制作物體的方法是 Mesh:
new THREE.Mesh(Geometry, Material);
Geometry 為物體的形狀,Material 為物體的材質(zhì);
1、形狀(Geometry)
three.js 給出了很多方法去生成固定的形狀,比如長(zhǎng)方體(BoxGeometry)、球體(SphereGeometry)、圓形(CircleGeometry)等等。還有根據(jù)坐標(biāo)去生成具體形狀的方法,可以借助第三方建模軟件建模之后引入,轉(zhuǎn)換為坐標(biāo)后再生成,就可以做比較復(fù)雜的形狀了,比如人臉、汽車(chē)等等。
在此以長(zhǎng)方體為例生成形狀:
//設(shè)置正方體寬度,高度,深度分別為5,5,5 var geometry = new THREE.BoxGeometry (5, 5, 5);
2、材質(zhì)(Material)
材質(zhì)就像是物體的皮膚,決定物體外表的樣子,例如物體的顏色,看起來(lái)是否光滑,是否有貼圖等等。
常用材質(zhì)有:
·網(wǎng)格基礎(chǔ)材質(zhì)(MeshBasicMaterial)
該材質(zhì)不受光照的影響,不需要光源即可顯示出來(lái),設(shè)置顏色后,各個(gè)面都是同一個(gè)顏色。
·網(wǎng)格法向材質(zhì)(MeshNormalMaterial)
該材質(zhì)不受光照的影響,不需要光源即可顯示出來(lái),并且每個(gè)方向的面的顏色都不同,同但一個(gè)方向的面顏色是相同的,
該材質(zhì)一般用于調(diào)試。
·網(wǎng)格朗博材質(zhì)(MeshLambertMaterial)
該材質(zhì)會(huì)受到光照的影響,沒(méi)有光源時(shí)不會(huì)顯示出來(lái),用于創(chuàng)建表面暗淡,不光亮的物體。
·網(wǎng)格 Phong 材質(zhì)(MeshPhongMaterial)
該材質(zhì)會(huì)受到光照的影響,沒(méi)有光源時(shí)不會(huì)顯示出來(lái),用于創(chuàng)建光亮的物體。
在此以網(wǎng)格 Phong 材質(zhì)為例創(chuàng)建材質(zhì):
var material = new THREE.MeshPhongMaterial({
color: "yellow" //設(shè)置顏色為yellow
});
創(chuàng)建形狀和材質(zhì)之后,就可以創(chuàng)建該物體了:
//創(chuàng)建物體 var cube = new THREE.Mesh(geometry, material);
7、 渲染畫(huà)布
通過(guò)以上步驟,我們已經(jīng)有了渲染器(renderer)、場(chǎng)景(scene)、照相機(jī)(camera)、光源(light)和物體(cube),此時(shí)我們需要將光源和物體加入場(chǎng)景中:
scene.add(light); scene.add(cube);
然后再使用渲染器將場(chǎng)景和照相機(jī)渲染出來(lái):
renderer.render(scene, camera);
效果如下圖:

四、 結(jié)束語(yǔ)
在以上內(nèi)容中,只寫(xiě)到了 Three.js 中提供的基礎(chǔ)功能,還有很多高級(jí)的功能需要大家去探索。希望大家看完這篇文章后能對(duì) Three.js 有一個(gè)初步的了解,并能夠使用 Three.js 繪制出基礎(chǔ)的 3D 圖形。
大家可以去 Three.js 官網(wǎng)的 examples 中看看,這里面都是一些很優(yōu)秀和典型的 examples,并且還有代碼可以下載,大家可以去研究探索一番。
在此附上幾個(gè)精彩的例子供大家欣賞:



總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
js實(shí)現(xiàn)點(diǎn)贊按鈕功能的實(shí)例代碼
這篇文章主要介紹了js實(shí)現(xiàn)點(diǎn)贊按鈕功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的工作或?qū)W習(xí)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
inquirer.js一個(gè)用戶(hù)與命令行交互的工具詳解
這篇文章主要介紹了inquirer.js一個(gè)用戶(hù)與命令行交互的工具詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05
如何用js將blob為pcm格式轉(zhuǎn)換為MP3格式
要將PCM文件轉(zhuǎn)換為MP3文件,您可以使用Js實(shí)現(xiàn),這篇文章主要給大家介紹了關(guān)于如何用js將blob為pcm格式轉(zhuǎn)換為MP3格式的相關(guān)資料,需要的朋友可以參考下2023-11-11
Javascript 生成無(wú)限下拉列表實(shí)現(xiàn)代碼
js生成無(wú)線(xiàn)下拉列表的實(shí)現(xiàn)代碼。2009-03-03
使用Cookies保存網(wǎng)站歷史瀏覽記錄實(shí)例代碼
仿淘寶網(wǎng)的最近瀏覽記錄功能,喜歡的朋友可以參考下。2010-07-07

