[轉] 基於Three.js的 Web 3D開發入門


轉載出處:https://www.jianshu.com/p/7ccf43f912bc

導語

隨着軟硬件的發展,在PC和移動端瀏覽器上進行web 3D開發的條件已經基本成熟了,出現了不少js 3D庫,Threejs是js 3D庫中的佼佼者。
國內也有企業開始做一些應用嘗試,某寶2016年雙11就用ThreeJS做了一個比較酷炫的3D宣傳頁面刷爆了朋友圈。
下圖是用Threejs繪制的一個3D立方體動畫的截圖,在這個demo里,立方體會動態的旋轉,threeJS 30行代碼就可以完成這么一個demo。
Threejs讓沒有豐富3D編程經驗的web前端開發人員,也可以快速上手開發web 3D應用。

Threejs是什么

官網對Threejs的介紹非常簡單:“Javascript 3D library”。
OpenGL是一個跨平台3D/2D的繪圖標准,WebGL則是openGL在瀏覽器上的一個實現。
web前端開發人員可以直接用WebGL接口進行編程,但WebGL只是非常基礎的繪圖API,需要編程人員有很多的數學知識、繪圖知識才能完成3D編程任務,而且代碼量巨大。
Threejs對WebGL進行了封裝,讓前端開發人員在不需要掌握很多數學知識和繪圖知識的情況下,也能夠輕松進行web 3D開發,降低了門檻,同時大大提升了效率。

Threejs應用場景舉例

1、web 3D游戲

2、3D模型展示

下圖的例子中,用戶可以跟瀏覽器交互,通過鼠標操作360度查看汽車,點擊車門進入到車內,查看車內立體視圖,如同身臨其境。

3、數據可視化

4、web vr

Threejs的基本要素

3D編程跟2D編程有較大不同,因此需要掌握一些3D編程的基本概念。Threejs的基本要素包括以下幾個方面:場景、相機、光、物體。
場景:是一個三維空間,所有物品的容器。可以把場景想象成一個空房間,接下來我們會往房間里面放要呈現的物體、相機、光源。

相機:Threejs必須要有往場景中添加一個相機,相機用來確定觀察位置、方向、角度,相機看到的內容,就是我們最終在屏幕上看到的內容。在程序運行過程中,可以調整相機的位置、方向、角度。想象一下,在房間里放了一個攝像機,你不在房間里面,但可以遠程控制相機移動,攝像機傳給遠程電腦上展示出來的畫面,就是Threejs在屏幕上呈現的畫面。

:假如沒有光,攝像機看不到任何東西,因此需要往場景中添加光源。為了跟真實世界更加接近,Threejs支持模擬不同光源,展現不同光照效果,有點光源、平行光、聚光燈、環境光等。

物體:有了場景、相機、光,就可以往場景中放物體了,在Threejs中,物體由形狀和材質兩部分組成,形狀決定物品的輪廓,材質則是物體的材料和質感。

渲染

Threejs繪制的東西,最終需要在屏幕一塊矩形畫布上顯示出來。
為了實現動畫效果,我們需要有一個重繪機制。
由於視神經元的反應速度問題,圖像消失后仍然會在人眼殘留1/24秒,只要一秒內繪制的幀數超過24就能實現流暢的動畫效果。
Threejs提供了重繪接口,我們有兩種方式去調用接口實現重繪。
一種是setInterval,以固定的時間間隔去調用,可以用於我們對渲染幀數要求比較高的場景。
但事實上由於Javascript是單線程的,這種方式並不能100%保證相同的時間間隔調用,如果瀏覽器繁忙可能會導致setInterval的延遲執行。
第二種方式是requestAnimationFrame,讓瀏覽器自行根據當前cpu負載等情況決定何時重繪,達到最佳幀率。

位置

為了方便描述位置,引入了坐標系,Threejs使用的是右手坐標系,如下圖所示。
坐標系的原點位於渲染畫布的幾何中心。我們對物體的位置的描述,也是指物體的幾何中心的位置。

相機

相機有正交投影相機和透視投影相機兩種。透視投影跟人眼看到的世界是一樣的,近大遠小;正交投影則遠近都是一樣的大小,三維空間中平行的線,投影到二維空間也一定是平行的。大部分場景都適合使用透視投影相機,因為跟真實世界的觀測效果一樣;在制圖、建模等場景適合使用正交投影相機,方便觀察模型之間的大小比例。

Threejs中的相機跟真實世界的相機不完全一樣,這里相機的可見區域是一個立方體,稱為相機的示景體。

正交投影相機

視景體是一個長方體,由6個參數確定:THREE.OrthographicCamera(left, right, top, bottom, near, far),這6個參數規定了相機示景體的左、右、上、下、前、后六個面的位置。

透視投影相機

視景體是一個梯形體,由四個參數確定:THREE.PerspectiveCamera(fov, aspect, near, far)

fov是相機在豎直方向的張角,aspect則是寬高比,即width/height,通常設為畫布的寬高比,near和far分別是近平面和遠平面與相機的距離。

投影的大小

考慮一種比較簡單的場景,相機示景體的遠近平面和坐標系中的xy平面平行,從而示景體遠近平面上的內容剛好可以垂直投影到畫布上,並且示景體中與xy平面平行的任何一個平面,投影到畫布上剛好等於畫布大小。假如透視投影相機的近平面的大小為axb,遠平面大小為2ax2b,則一張axb大小的紙放在近平面上,投影到畫布時剛好鋪滿整張畫布;放到遠平面上則只能占據畫布面積的1/4(遠平面的面積是近平面的4倍)。正是因為透視投影相機的示景體近小遠大,才會導致同樣一個物品放在不同位置顯示出近大遠小的效果。而正交投影相機因為遠近平面大小一樣,所以同一個物品距離相機的遠近不影響物體在畫布上投影展示的大小。

物體

物體由幾何形狀(Geometry)和材質(Material)組成。同樣的幾何形狀,不同材質構成了不同物體,比如球狀,有籃球、玻璃球、水晶球等。

形狀

Threejs提供了一些常見的幾何形狀,有三維的也有二維的,三維的比如長方體、球體、圓柱體、環等,二維的比如長方形、圓形、扇形等。如果默認提供的形狀不能滿足需求,也可以自定義,通過定義頂點和頂點之間的連線繪制自定義幾何形狀,更復雜的模型還可以用建模軟件建模后導入。

計算機是如何繪制幾何形狀的呢?我們知道,計算機只能繪制直線,那么曲線和3D形狀如何繪制出來呢?

1、繪制圓形。如下圖所示,通過繪制多邊形實現近似的圓形效果,當多邊形的邊數足夠多的時候,兩條邊之間的過渡就顯得平滑,多邊形看起來就足夠圓了。

2、繪制3D模型。
常用的做法是用三角形組成的網格來模擬,如下圖所示,用足夠多的三角形時,兔子的身體看起來就足夠平滑,跟真實兔子比較接近。
著名的斯坦福兔子模型用了69451個三角形。


材質

Threejs提供了幾種比較有代表性的材質,常用的有漫反射、鏡面反射兩種材質,還可以引入外部圖片,貼到物體表面,稱為紋理貼圖。

外部模型

現實世界豐富多彩,不是Threejs的幾種默認幾何形狀和材質所能表達的。
實際運用中,很多時候需要用到外部模型,通過3D建模軟件構建物體的三維模型並導出模型文件,Threejs導入模型文件進行使用。

光照

光源主要是以下幾種:
1)、環境光,所有角度看到的亮度一樣,通常用來為整個場景指定一個基礎亮度,沒有明確光源位置;
2)、點光源,一個點發出的光源,照到不同物體表面的亮度線性遞減;
3)、平行光,亮度與光源和物體之間的距離無關,只與平行光的角度和物體所在平面有關;
4)、聚光燈,投射出的是類似圓錐形的光線。

小結

本文對Threejs編程做了一下簡單介紹,目的是讓讀者對Threejs編程有個基本認識。
紙上得來終覺淺,絕知此事要躬行!
建議到Threejs官網首頁看看那些有趣的demo,着手寫一些簡單的demo進行實踐。
目前web 3D應用因為瀏覽器渲染性能、模型體積過大等原因,並沒有大規模使用起來,只限於在品牌宣傳等部分領域嘗試使用。
我剛好經歷過瀏覽器2D數據可視化繪圖由flash向JS轉變的過程(2012年前后),相信隨着軟硬件性能的提升和網絡速度的提升,web 3D應用也會慢慢的推廣使用起來。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM