偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Three.js - 走進(jìn)3D的奇妙世界

開發(fā) 前端 開發(fā)工具
Three.js是用于實(shí)現(xiàn)web端3D效果的JS庫(kù),它的出現(xiàn)讓3D應(yīng)用開發(fā)更簡(jiǎn)單,本文將通過(guò)Three.js的介紹及示例帶我們走進(jìn)3D的奇妙世界。

隨著人們對(duì)用戶體驗(yàn)越來(lái)越重視,Web開發(fā)已經(jīng)不滿足于2D效果的實(shí)現(xiàn),而把目標(biāo)放到了更加炫酷的3D效果上。Three.js是用于實(shí)現(xiàn)web端3D效果的JS庫(kù),它的出現(xiàn)讓3D應(yīng)用開發(fā)更簡(jiǎn)單,本文將通過(guò)Three.js的介紹及示例帶我們走進(jìn)3D的奇妙世界。

一、Three.js相關(guān)概念

1.1 Three.JS

Three.JS是基于WebGL的Javascript開源框架,簡(jiǎn)言之,就是能夠?qū)崿F(xiàn)3D效果的JS庫(kù)。

1.2 WebGL

WebGL是一種Javascript的3D圖形接口,把JavaScript和OpenGL ES 2.0結(jié)合在一起。

1.3 OpenGL

OpenGL是開放式圖形標(biāo)準(zhǔn),跨編程語(yǔ)言、跨平臺(tái),Javascript、Java 、C、C++ 、 python 等都能支持OpenG ,OpenGL的Javascript實(shí)現(xiàn)就是WebGL,另外很多CAD制圖軟件都采用這種標(biāo)準(zhǔn)。OpenGL ES 2.0是OpenGL的子集,針對(duì)手機(jī)、游戲主機(jī)等嵌入式設(shè)備而設(shè)計(jì)。

1.4 Canvas

Canvas是HTML5的畫布元素,在使用Canvas時(shí),需要用到Canvas的上下文,可以用2D上下文繪制二維的圖像,也可以使用3D上下文繪制三維的圖像,其中3D上下文就是指WebGL。

二、Three.js應(yīng)用場(chǎng)景

利用Three.JS可以制作出很多酷炫的3D動(dòng)畫,并且Three.js還可以通過(guò)鼠標(biāo)、鍵盤、拖拽等事件形成交互,在頁(yè)面上增加一些3D動(dòng)畫和3D交互可以產(chǎn)生更好的用戶體驗(yàn)。

通過(guò)Three.JS可以實(shí)現(xiàn)全景視圖,這些全景視圖應(yīng)用在房產(chǎn)、家裝行業(yè)能夠帶來(lái)更直觀的視覺體驗(yàn)。在電商行業(yè)利用Three.JS可以實(shí)現(xiàn)產(chǎn)品的3D效果,這樣用戶就可以360度全方位地觀察商品了,給用戶帶來(lái)更好的購(gòu)物體驗(yàn)。另外,使用Three.JS還可以制作類似微信跳一跳那樣的小游戲。隨著技術(shù)的發(fā)展、基礎(chǔ)網(wǎng)絡(luò)的建設(shè),web3D技術(shù)還能得到更廣泛的應(yīng)用。

[[284072]]

三、主要組件

在Three.js中,有了場(chǎng)景(scene)、相機(jī)(camera)和渲染器(renderer) 這3個(gè)組建才能將物體渲染到網(wǎng)頁(yè)中去。

1)場(chǎng)景

場(chǎng)景是一個(gè)容器,可以看做攝影的房間,在房間中可以布置背景、擺放拍攝的物品、添加燈光設(shè)備等。

2)相機(jī)

相機(jī)是用來(lái)拍攝的工具,通過(guò)控制相機(jī)的位置和方向可以獲取不同角度的圖像。

3)渲染器

渲染器利用場(chǎng)景和相機(jī)進(jìn)行渲染,渲染過(guò)程好比攝影師拍攝圖像,如果只渲染一次就是靜態(tài)的圖像,如果連續(xù)渲染就能得到動(dòng)態(tài)的畫面。在JS中可以使用requestAnimationFrame實(shí)現(xiàn)高效的連續(xù)渲染。

3.1 常用相機(jī)

1)透視相機(jī)

透視相機(jī)模擬的效果與人眼看到的景象最接近,在3D場(chǎng)景中也使用得最普遍,這種相機(jī)最大的特點(diǎn)就是近大遠(yuǎn)小,同樣大小的物體離相機(jī)近的在畫面上顯得大,離相機(jī)遠(yuǎn)的物體在畫面上顯得小。透視相機(jī)的視錐體如上圖左側(cè)所示,從近端面到遠(yuǎn)端面構(gòu)成的區(qū)域內(nèi)的物體才能顯示在圖像上。

透視相機(jī)構(gòu)造器

PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )

  •  fov — 攝像機(jī)視錐體垂直視野角度
  •  aspect — 攝像機(jī)視錐體長(zhǎng)寬比
  •  near — 攝像機(jī)視錐體近端面
  •  far — 攝像機(jī)視錐體遠(yuǎn)端面

2)正交相機(jī)

使用正交相機(jī)時(shí)無(wú)論物體距離相機(jī)遠(yuǎn)或者近,在最終渲染的圖片中物體的大小都保持不變。正交相機(jī)的視錐體如上圖右側(cè)所示,和透視相機(jī)一樣,從近端面到遠(yuǎn)端面構(gòu)成的區(qū)域內(nèi)的物體才能顯示在圖像上。

正交相機(jī)構(gòu)造器

OrthographicCamera( left : Number, right : Number, top : Number, bottom : Number, near : Number, far : Number )

  •  left — 攝像機(jī)視錐體左側(cè)面
  •  right — 攝像機(jī)視錐體右側(cè)面
  •  top — 攝像機(jī)視錐體上側(cè)面
  •  bottom — 攝像機(jī)視錐體下側(cè)面
  •  near — 攝像機(jī)視錐體近端面
  •  far — 攝像機(jī)視錐體遠(yuǎn)端面

3.2 坐標(biāo)系

在場(chǎng)景中,可以放物品、相機(jī)、燈光,這些東西放置到什么位置就需要使用坐標(biāo)系。Three.JS使用右手坐標(biāo)系,這源于OpenGL默認(rèn)情況下,也是右手坐標(biāo)系。從初中、高中到大學(xué)的課堂上,教材中所涉及的幾何基本都是右手坐標(biāo)系。

上圖右側(cè)就是右手坐標(biāo)系,五指并攏手指放平,指尖指向x軸的正方向,然后把四個(gè)手指垂直彎曲大拇指分開,并攏的四指指向y軸的正方向,大拇指指向的就是Z軸的正方向。

在Three.JS中提供了坐標(biāo)軸工具(THREE.AxesHelper),在場(chǎng)景中添加坐標(biāo)軸后,畫面會(huì)出現(xiàn)3條垂直相交的直線,紅色表示x軸,綠色表示y軸,藍(lán)色表示z軸(如下圖所示)。

3.3 示例代碼 

  1. /* 場(chǎng)景 */  
  2. var scene = new THREE.Scene();  
  3. scene.add(new THREE.AxesHelper(10)); // 添加坐標(biāo)軸輔助線  
  4. /* 幾何體 */  
  5. // 這是自定義的創(chuàng)建幾何體方法,如果創(chuàng)建幾何體后續(xù)會(huì)介紹  
  6. var kleinGeom = createKleinGeom();   
  7. scene.add(kleinGeom); // 場(chǎng)景中添加幾何體  
  8. /* 相機(jī) */  
  9. var camera = new THREE.PerspectiveCamera(45, width/height, 1, 100);  
  10. camera.position.set(5,10,25); // 設(shè)置相機(jī)的位置  
  11. camera.lookAt(new THREE.Vector3(0, 0, 0)); // 相機(jī)看向原點(diǎn)  
  12. /* 渲染器 */  
  13. var renderer = new THREE.WebGLRenderer({antialias:true});  
  14. renderer.setSize(width, height);  
  15. // 將canvas元素添加到body  
  16. document.body.appendChild(renderer.domElement);  
  17. // 進(jìn)行渲染  
  18. renderer.render(scene, camera); 

四、幾何體

計(jì)算機(jī)內(nèi)的3D世界是由點(diǎn)組成,兩個(gè)點(diǎn)能夠組成一條直線,三個(gè)不在一條直線上的點(diǎn)就能夠組成一個(gè)三角形面,無(wú)數(shù)三角形面就能夠組成各種形狀的幾何體。

以創(chuàng)建一個(gè)簡(jiǎn)單的立方體為例,創(chuàng)建簡(jiǎn)單的立方體需要添加8個(gè)頂點(diǎn)和12個(gè)三角形的面,創(chuàng)建頂點(diǎn)時(shí)需要指定頂點(diǎn)在坐標(biāo)系中的位置,添加面的時(shí)候需要指定構(gòu)成面的三個(gè)頂點(diǎn)的序號(hào),第一個(gè)添加的頂點(diǎn)序號(hào)為0,第二個(gè)添加的頂點(diǎn)序號(hào)為1…

創(chuàng)建立方體的代碼如下: 

  1. var geometry = new THREE.Geometry();  
  2. // 添加8個(gè)頂點(diǎn)  
  3. geometry.vertices.push(new THREE.Vector3(1, 1, 1));  
  4. geometry.vertices.push(new THREE.Vector3(1, 1, -1));  
  5. geometry.vertices.push(new THREE.Vector3(1, -1, 1));  
  6. geometry.vertices.push(new THREE.Vector3(1, -1, -1));  
  7. geometry.vertices.push(new THREE.Vector3(-1, 1, -1));  
  8. geometry.vertices.push(new THREE.Vector3(-1, 1, 1));  
  9. geometry.vertices.push(new THREE.Vector3(-1, -1, -1));  
  10. geometry.vertices.push(new THREE.Vector3(-1, -1, 1));  
  11. // 添加12個(gè)三角形的面  
  12. geometry.faces.push(new THREE.Face3(0, 2, 1));  
  13. geometry.faces.push(new THREE.Face3(2, 3, 1));  
  14. geometry.faces.push(new THREE.Face3(4, 6, 5));  
  15. geometry.faces.push(new THREE.Face3(6, 7, 5));  
  16. geometry.faces.push(new THREE.Face3(4, 5, 1));  
  17. geometry.faces.push(new THREE.Face3(5, 0, 1));  
  18. geometry.faces.push(new THREE.Face3(7, 6, 2));  
  19. geometry.faces.push(new THREE.Face3(6, 3, 2));  
  20. geometry.faces.push(new THREE.Face3(5, 7, 0));  
  21. geometry.faces.push(new THREE.Face3(7, 2, 0));  
  22. geometry.faces.push(new THREE.Face3(1, 3, 4));  
  23. geometry.faces.push(new THREE.Face3(3, 6, 4)); 

4.1 正面和反面

創(chuàng)建幾何體的三角形面時(shí),指定了構(gòu)成面的三個(gè)頂點(diǎn),如: new THREE.Face3(0, 2, 1),如果把頂點(diǎn)的順序改成0,1,2會(huì)有區(qū)別嗎?

通過(guò)下圖可以看到,按照0,2,1添加頂點(diǎn)是順時(shí)針?lè)较虻模?,1,2添加頂點(diǎn)則是逆時(shí)針?lè)较虻?,通過(guò)添加頂點(diǎn)的方向就可以判斷當(dāng)前看到的面是正面還是反面,如果頂點(diǎn)是逆時(shí)針?lè)较蛱砑?,?dāng)前看到的面是正面,如果頂點(diǎn)是順時(shí)針?lè)较蛱砑樱瑒t當(dāng)前面為反面。

下圖所看到的面就是反面。如果不好記,可以使用右手沿頂點(diǎn)添加的方向握住,大拇指所在的面就是正面,很像我們上學(xué)時(shí)學(xué)的電磁感應(yīng)定律。

五、材質(zhì)

創(chuàng)建幾何體時(shí)通過(guò)指定幾何體的頂點(diǎn)和三角形的面確定了幾何體的形狀,另外還需要給幾何體添加皮膚才能實(shí)現(xiàn)物體的效果,材質(zhì)就像物體的皮膚,決定了物體的質(zhì)感。常見的材質(zhì)有如下幾種:

  •  基礎(chǔ)材質(zhì):以簡(jiǎn)單著色方式來(lái)繪制幾何體的材質(zhì),不受光照影響。
  •  深度材質(zhì):按深度繪制幾何體的材質(zhì)。深度基于相機(jī)遠(yuǎn)近端面,離近端面越近就越白,離遠(yuǎn)端面越近就越黑。
  •  法向量材質(zhì):把法向量映射到RGB顏色的材質(zhì)。
  •  Lambert材質(zhì):是一種需要光源的材質(zhì),非光澤表面的材質(zhì),沒(méi)有鏡面高光,適用于石膏等表面粗糙的物體。
  •  Phong材質(zhì):也是一種需要光源的材質(zhì),具有鏡面高光的光澤表面的材質(zhì),適用于金屬、漆面等反光的物體。
  •  材質(zhì)捕獲:使用存儲(chǔ)了光照和反射等信息的貼圖,然后利用法線方向進(jìn)行采樣。優(yōu)點(diǎn)是可以用很低的消耗來(lái)實(shí)現(xiàn)很多特殊風(fēng)格的效果;缺點(diǎn)是僅對(duì)于固定相機(jī)視角的情況較好。

下圖是使用不同貼圖實(shí)現(xiàn)的效果:

六、光源

前面提到的光敏材質(zhì)(Lambert材質(zhì)和Phong材質(zhì))需要使用光源來(lái)渲染出3D效果,在使用時(shí)需要將創(chuàng)建的光源添加到場(chǎng)景中,否則無(wú)法產(chǎn)生光照效果。下面介紹一下常用的光源及特點(diǎn)。

6.1 點(diǎn)光源

點(diǎn)光源類似蠟燭放出的光,不同的是蠟燭有底座,點(diǎn)光源沒(méi)有底座,可以把點(diǎn)光源想象成懸浮在空中的火苗,點(diǎn)光源放出的光線來(lái)自同一點(diǎn),且方向輻射向四面八方,點(diǎn)光源在傳播過(guò)程中有衰弱,如下圖所示,點(diǎn)光源在接近地面的位置,物體底部離點(diǎn)光源近,物體頂部離光源遠(yuǎn),照到物體頂部的光就弱些,所以頂部會(huì)比底部暗些。

6.2 平行光

平行光模擬的是太陽(yáng)光,光源發(fā)出的所有光線都是相互平行的,平行光沒(méi)有衰減,被平行光照亮的整個(gè)區(qū)域接受到的光強(qiáng)是一樣的。

6.3 聚光燈

類似舞臺(tái)上的聚光燈效果,光源的光線從一個(gè)錐體中射出,在被照射的物體上產(chǎn)生聚光的效果。聚光燈在傳播過(guò)程也是有衰弱的。

6.4 環(huán)境光

環(huán)境光是經(jīng)過(guò)多次反射而來(lái)的光,環(huán)境光源放出的光線被認(rèn)為來(lái)自任何方向,物體無(wú)論法向量如何,都將表現(xiàn)為同樣的明暗程度。

環(huán)境光通常不會(huì)單獨(dú)使用,通過(guò)使用多種光源能夠?qū)崿F(xiàn)更真實(shí)的光效,下圖是將環(huán)境光與點(diǎn)光源混合后實(shí)現(xiàn)的效果,物體的背光面不像點(diǎn)光源那樣是黑色的,而是呈現(xiàn)出深褐色,更自然。

七、紋理

在生活中純色的物體還是比較少的,更多的是有凹凸不平的紋路或圖案的物體,要用Three.JS實(shí)現(xiàn)這些物體的效果,就需要使用到紋理貼圖。3D世界的紋理是由圖片組成的,將紋理添加在材質(zhì)上以一定的規(guī)則映射到幾何體上,幾何體就有了帶紋理的皮膚。

7.1 普通紋理貼圖

在這個(gè)示例中使用上圖左側(cè)的地球紋理,在球形幾何體上進(jìn)行貼圖就能制作出一個(gè)地球。

代碼如下: 

  1. /* 創(chuàng)建地球 */  
  2. function createGeom() {  
  3.     // 球體  
  4.     var geom = new THREE.SphereGeometry(1, 64, 64);  
  5.     // 紋理  
  6.     var loader = new THREE.TextureLoader();  
  7.     var texture = loader.load('./earth.jpg');  
  8.     // 材質(zhì)  
  9.     var material = new THREE.MeshLambertMaterial({  
  10.         map: texture  
  11.     });  
  12.     var earth = new THREE.Mesh(geom, material);  
  13.     return earth;  

7.2 反面貼圖實(shí)現(xiàn)全景視圖

這個(gè)例子是通過(guò)在球形幾何體的反面進(jìn)行紋理貼圖實(shí)現(xiàn)的全景視圖,實(shí)現(xiàn)原理是這樣的:創(chuàng)建一個(gè)球體構(gòu)成一個(gè)球形的空間,把相機(jī)放在球體的中心,相機(jī)就像在一個(gè)球形的房間中,在球體的里面(也就是反面)貼上圖片,通過(guò)改變相機(jī)拍攝的方向,就能看到全景視圖了。

材質(zhì)默認(rèn)是在幾何體的正面進(jìn)行貼圖的,如果想要在反面貼圖,需要在創(chuàng)建材質(zhì)的時(shí)候設(shè)置side參數(shù)的值為THREE.BackSide,代碼如下: 

  1. /* 創(chuàng)建反面貼圖的球形 */  
  2. // 球體  
  3. var geom = new THREE.SphereGeometry(500, 64, 64);  
  4. // 紋理  
  5. var loader = new THREE.TextureLoader();  
  6. var texture = loader.load('./panorama.jpg');  
  7. // 材質(zhì)  
  8. var material = new THREE.MeshBasicMaterial({  
  9.     map: texture,  
  10.     side: THREE.BackSide  
  11. });  
  12. var panorama = new THREE.Mesh(geom, material); 

7.3 凹凸紋理貼圖

凹凸紋理利用黑色和白色值映射到與光照相關(guān)的感知深度,不會(huì)影響對(duì)象的幾何形狀,只影響光照,用于光敏材質(zhì)(Lambert材質(zhì)和Phong材質(zhì))。

如果只用上圖左上角的磚墻圖片進(jìn)行貼圖的話,就像一張墻紙貼在上面,視覺效果很差,為了增強(qiáng)立體感,可以使用上圖左下角的凹凸紋理,給物體增加凹凸不平的效果。

凹凸紋理貼圖使用方式的代碼如下: 

  1. // 紋理加載器  
  2. var loader = new THREE.TextureLoader();  
  3. // 紋理  
  4. var texture = loader.load( './stone.jpg');  
  5. // 凹凸紋理  
  6. var bumpTexture = loader.load( './stone-bump.jpg');  
  7. // 材質(zhì)  
  8. var material =  new THREE.MeshPhongMaterial( {  
  9.     map: texture,  
  10.     bumpMap: bumpTexture  
  11. } ); 

7.4 法線紋理貼圖

法線紋理也是通過(guò)影響光照實(shí)現(xiàn)凹凸不平視覺效果的,并不會(huì)影響物體的幾何形狀,用于光敏材質(zhì)(Lambert材質(zhì)和Phong材質(zhì))。上圖左下角的法線紋理圖片的RGB值會(huì)影響每個(gè)像素片段的曲面法線,從而改變物體的光照效果。

使用方式的代碼如下: 

  1. // 紋理  
  2. var texture = loader.load( './metal.jpg');  
  3. // 法線紋理  
  4. var normalTexture = loader.load( './metal-normal.jpg');  
  5. var material =  new THREE.MeshPhongMaterial( {  
  6.     map: texture,  
  7.     normalMap: normalTexture  
  8. } ); 

7.5 環(huán)境貼圖

環(huán)境貼圖是將當(dāng)前環(huán)境作為紋理進(jìn)行貼圖,能夠模擬鏡面的反光效果。在進(jìn)行環(huán)境貼圖時(shí)需要使用立方相機(jī)在當(dāng)前場(chǎng)景中進(jìn)行拍攝,從而獲得當(dāng)前環(huán)境的紋理。立方相機(jī)在拍攝環(huán)境紋理時(shí),為避免反光效果的小球出現(xiàn)在環(huán)境紋理的畫面上,需要將小球設(shè)為不可見。

環(huán)境貼圖的主要代碼如下: 

  1. /* 立方相機(jī) */  
  2. var cubeCamera = new THREE.CubeCamera( 1, 10000, 128 );  
  3. /* 材質(zhì) */  
  4. var material = new THREE.MeshBasicMaterial( {  
  5.     envMap: cubeCamera.renderTarget.texture  
  6. });  
  7. /* 鏡面反光的球體 */  
  8. var geom = new THREE.SphereBufferGeometry( 10, 32, 16 );  
  9. var ball = new THREE.Mesh( geom, material );  
  10. // 將立方相機(jī)添加到球體  
  11. ball.add( cubeCamera );  
  12. scene.add( ball );  
  13. // 立方相機(jī)生成環(huán)境紋理前將反光小球隱藏  
  14. ball.visible = false 
  15. // 更新立方相機(jī),生成環(huán)境紋理  
  16. cubeCamera.update( renderer, scene );  
  17. balls.visible = true 
  18. // 渲染  
  19. renderer.render(scene, camera); 

八、加載外部3D模型

Three.JS已經(jīng)內(nèi)置了很多常用的幾何體,如:球體、立方體、圓柱體等等,但是在實(shí)際使用中往往需要用到一些特殊形狀的幾何體,這時(shí)可以使用3D建模軟件制作出3D模型,導(dǎo)出obj、json、gltf等格式的文件,然后再加載到Three.JS渲染出效果。

上圖的椅子是在3D制圖軟件繪制出來(lái)的,chair.mtl是導(dǎo)出的材質(zhì)文件,chair.obj是導(dǎo)出的幾何體文件,使用材質(zhì)加載器加載材質(zhì)文件,加載完成后得到材質(zhì)對(duì)象,給幾何體加載器設(shè)置材質(zhì),加載后得到幾何體對(duì)象,然后再創(chuàng)建場(chǎng)景、光源、攝像機(jī)、渲染器等進(jìn)行渲染,這樣就等得到如圖的效果。主要的代碼如下: 

  1. // .mtl材質(zhì)文件加載器  
  2. var mtlLoader = new THREE.MTLLoader();  
  3. // .obj幾何體文件加載器  
  4. var objLoader = new THREE.OBJLoader();  
  5. mtlLoader.load('./chair.mtl', function (materials) {  
  6.     objLoader.setMaterials(materials)  
  7.         .load('./chair.obj', function (obj) {  
  8.             scene.add(obj);  
  9.             …  
  10.         });  
  11. }); 

九、說(shuō)明

以上內(nèi)容對(duì)Three.JS的基本使用進(jìn)行了介紹,文中涉及到的示例源碼已上傳到github,感興趣的同學(xué)可以下載查看,下載地址:https://github.com/liulinsp/t...。使用時(shí)如果有不清楚的地方可以查看Three.JS的官方文檔:https://threejs.org/docs/inde...。

 

 

責(zé)任編輯:龐桂玉 來(lái)源: segmentfault
相關(guān)推薦

2024-07-18 06:58:36

2022-01-16 19:23:25

Three.js粒子動(dòng)畫群星送福

2021-11-27 10:42:01

Three.js3D可視化AudioContex

2021-11-23 22:50:14

.js 3D幾何體

2023-07-13 10:48:22

web 3DThree.jsBlender

2025-06-30 09:15:47

2021-04-21 09:20:15

three.js3d前端

2016-06-01 09:19:08

開發(fā)3D游戲

2023-08-04 09:56:15

2024-02-26 00:00:00

前端工具Space.js

2022-07-15 13:09:33

Three.js前端

2021-11-22 06:14:45

Three.js3D 渲染花瓣雨

2017-05-08 11:41:37

WebGLThree.js

2023-09-01 09:30:22

Three.js3D 圖形庫(kù)

2022-09-14 09:23:51

Java3D引擎

2021-12-07 13:44:43

Three.js3D可視化3D 游戲

2012-12-24 08:48:25

iOSUnity3D

2025-05-15 08:45:00

開源前端手勢(shì)

2021-04-23 16:40:49

Three.js前端代碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)