寫在前面,好久不見各位,之前一段時間因為一些事情有點忙,但從未停止學習的腳步,也屯了很多筆記,會在未來的時間慢慢發出來,從今天開始一起進入WebGis,threeJs目前大前端發展的一個方向開始學習,希望裡面可以有幫助到大家的內容,有不足的地方還請指正,一起學習進步!!!
1.瞭解Three.js
近年來web得到了快速的發展。隨著HTML5的普及,網頁的表現能力越來越強大。網頁上已經可以做出很多複雜的動畫,精美的效果。還能透過WebGL在網頁中繪製高效能的3D圖形。
隨著瀏覽器效能和網路頻寬的大幅度提升,以及WebGL的實現,使得3D技術不再是桌面程式的專利,越來越多的Web應用使用3D技術。
對網站而言,Web3D技術運用,實現企業網站三維呈現,讓企業形象更直觀、更立體地展現給客戶,打破傳統平面展示模式,打造智慧、個性、創新的企業形象。目前政府有大量的新基建專案,如數字孿生、智慧城市、智慧園區、智慧工廠等等都涉及到了3D視覺化技術。
今天就來給大家講講如何系統的學好WEB 3D視覺化技術。
我們可以先從threejs庫入手。threejs是一個讓使用者透過javascript入手進入搭建webgl專案的類庫。眾所周知學習webgl需要圖形學知識,而webgl需要透過js和glsl兩種語言。如果我們不透過threejs使用webgl勢必逃不過底層知識:你必須全面瞭解著色器語法和自己編寫頂點著色片元著色;但你使用了threejs顯然可以便捷的逃過這些難懂的底層,對於傳統js從業人員直接挑戰的shader確實是有難度的。
學習three.js首先掌握基礎概念什麼是點、線、面、幾何體、材質、物體、場景、相機、渲染器、動畫、控制器等基礎概念,搞定一個最基礎的場景和3d物體的顯示。接著學會除錯3D開發程式碼。接著即可深入上訴概念的每一個概念,詳細瞭解官網文件該類的各種屬性與概念。
接著3d渲染要真實性,肯定離不開PBR,詳細瞭解什麼是PBR,PBR基於物理的光照原理的渲染,。掌握什麼是環境貼圖、凹凸貼圖、置換貼圖、放射光、,環境貼圖、金屬貼圖、粗糙度貼圖等等,去打造真實的物體顯示效果。接著掌握如何繪製粒子群,來繪製雨雪、落葉、星河等各種粒子效果,甚至產品的粒子效果。
掌握了這些,基本就算入了個小門了,接著就是要實現能和物體進行互動,如何選中與場景中的物體進行互動。而且還要能夠掌握物理引擎讓物體有真實的物理效果,例如重力,反彈、摩擦力等這樣物體相互作用會更加真實。
接著就要開始真正進入WEBGL魔力的世界,掌握著色器語言,控制GPU渲染,掌握實現three.js底層封裝的原理,能夠圖形渲染原理,掌握編寫頂點著色器和片元著色器,來繪製動態飄揚的旗幟。以及編寫動態的煙霧和烏雲,水紋。
掌握了這些就可以寫節日酷炫的煙花了,接著可以繼續掌握各種後期合成效果,對整個渲染畫面進行調整,例如打造閃爍的畫面,雪花感的陳舊電視畫面,又或者透過編寫著色器,打造出水底世界的效果。
接著掌握曲線和物體運動的結合,在加上著色器編寫,即可實現各種飛線、雷達、光牆特效。透過地理資訊資料,獲取建築資訊,可以生成建築的框架和高度渲染出數字城市。當然日常網頁也或有一些文字資訊標識,想要文字標識也加上3d效果,就需要掌握css3d的渲染器來渲染。當然如果需要掌握渲染精美真實的智慧園區的,就需要掌握建模技術,例如學習blender軟體搭建模型和最佳化模型,才能最終輸出到網頁中,包括動畫也可以先用blender做好在輸出到網頁中,不用辛苦的進行復雜動畫的編寫,可以視覺化的製作。
2.本地搭建Threejs官方文件網站
因為Three.js官網是國外的伺服器,所以為了方便學習和快速的查閱文件,我們可以自己搭建Three.js官網和文件,方便隨時檢視案例和文件內容進行學習。
1、首先進入threejs庫GitHub地址:https://github.com/mrdoob/three.js
2、下載完整程式碼
3、專案檔案解壓縮
4、命令列安裝依賴
一般安裝可以用npm、yarn等包管理工具,課程以yarn舉例,如果沒有安裝可以用npm install yarn -g進行安裝。
yarn install
5、啟動專案
yarn start
瀏覽器訪問即可:http://localhost:8080
6、文件目錄介紹
build目錄:
docs文件:
選擇中文,檢視中文文件。
examples案例:
可以透過網址,找到具體的案例程式碼,如此處的檔名稱是:webgl_animation_keyframes。因此可以在資料夾找到對應的程式碼檔案
editor目錄:
官方提供的視覺化編輯器,可以直接匯入模型,修改材質,新增光照效果等等。
3.使用vite搭建three.js開發環境
為了方便模組化進行three.js專案的學習和開發,又不用學習太多的配置,增加學習成本,所以就使用Parcel這個web應用打包工具。
Parcel官網:https://v2.parceljs.cn/getting-started/webapp/
1、安裝
選擇無框架,也可以vue框架
刪掉其他不相關,因為到時候three就是建立一個畫布
threeJS建立幾步曲
先建立場景,建立相機,建立渲染器,建立網格,設定相機位置,渲染相機
就有了最基本的網格在畫布中
如果想動起來
2、專案設定
現在已經安裝了 Parcel,讓我們為我們的應用程式建立一些原始檔。Parcel 接受任何型別的檔案作為入口點,但 HTML 檔案是一個很好的起點。Parcel 將從那裡遵循您的所有依賴項來構建您的應用程式。
建立src資料夾,並且建立index.html檔案
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./assets/css/style.css" />
</head>
<body>
<script src="./main/main.js" type="module"></script>
</body>
</html>
設定1個css檔案
* {
margin: 0;
padding: 0;
}
body {
background-color: skyblue;
}
建立一個main.js
import * as THREE from "three";
// console.log(THREE);
// 目標:瞭解three.js最基本的內容
// 1、建立場景
const scene = new THREE.Scene();
// 2、建立相機
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 設定相機位置
camera.position.set(0, 0, 10);
scene.add(camera);
// 新增物體
// 建立幾何體
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
// 根據幾何體和材質建立物體
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 將幾何體新增到場景中
scene.add(cube);
// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 設定渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// console.log(renderer);
// 將webgl渲染的canvas內容新增到body
document.body.appendChild(renderer.domElement);
// 使用渲染器,透過相機將場景渲染進來
renderer.render(scene, camera);
3、打包指令碼
到目前為止,我們一直在parcel直接執行 CLI,但在您的package.json檔案中建立一些指令碼以簡化此操作會很有用。我們還將設定一個指令碼來使用該命令構建您的應用程式以進行生產。parcel build最後,您還可以使用該欄位在一個地方宣告您的條目source,這樣您就不需要在每個parcel命令中重複它們。
package.json:
{
"name": "01-three_basic",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "parcel src/index.html",
"build": "parcel build src/index.html"
},
"author": "",
"license": "ISC",
"devDependencies": {
"parcel": "^2.4.1"
},
"dependencies": {
"dat.gui": "^0.7.9",
"gsap": "^3.10.3",
"three": "^0.139.2"
}
}
安裝依賴package.json設定的依賴
yarn install
現在您可以執行yarn build以構建您的生產專案並yarn dev啟動開發伺服器。
yarn dev
4.渲染第一個場景和物體
1 基本概念
三維的物體要渲染在二維的螢幕上。首先要建立一個場景來放置物體,那麼最終怎麼顯示三維的內容,就應該找一個相機,將相機放在場景的某個位置,然後想要顯示就要把相機拍的內容渲染出來。所以就引出三個基本概念:場景、相機、渲染器。
1.1 場景
three.js建立場景非常的簡單。
// 1、建立場景
const scene = new THREE.Scene();
1.2 相機
three.js建立相機物件
// 2、建立相機
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 設定相機位置
camera.position.set(0, 0, 10);
three.js裡有幾種不同的相機,在這裡,我們使用的是PerspectiveCamera(透視攝像機)。
第一個引數是視野角度(FOV)。視野角度就是無論在什麼時候,你所能在顯示器上看到的場景的範圍,它的單位是角度(與弧度區分開)。
第二個引數是長寬比(aspect ratio)。 也就是你用一個物體的寬除以它的高的值。比如說,當你在一個寬屏電視上播放老電影時,可以看到影像彷彿是被壓扁的。
接下來的兩個引數是近截面(near)和遠截面(far)。 當物體某些部分比攝像機的遠截面遠或者比近截面近的時候,該這些部分將不會被渲染到場景中。或許現在你不用擔心這個值的影響,但未來為了獲得更好的渲染效能,你將可以在你的應用程式裡去設定它。
下圖椎體就是上面設定視野角度、長寬比、近截面和遠截面的演示的相機透視椎體。
1.3 渲染器
接下來是渲染器。這裡是施展魔法的地方。
// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 設定渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// console.log(renderer);
// 將webgl渲染的canvas內容新增到body
document.body.appendChild(renderer.domElement);
// 使用渲染器,透過相機將場景渲染進來
renderer.render(scene, camera);
除了建立一個渲染器的例項之外,我們還需要在我們的應用程式裡設定一個渲染器的尺寸。比如說,我們可以使用所需要的渲染區域的寬高,來讓渲染器渲染出的場景填充滿我們的應用程式。因此,我們可以將渲染器寬高設定為瀏覽器視窗寬高。對於效能比較敏感的應用程式來說,你可以使用setSize傳入一個較小的值,例如window.innerWidth/2和window.innerHeight/2,這將使得應用程式在渲染時,以一半的長寬尺寸渲染場景。
接下來將renderer(渲染器)的dom元素(renderer.domElement)新增到我們的HTML文件中。渲染器用來顯示場景給我們看的
最後就是對將相機對場景進行拍照渲染啦。這一句就可以將畫面渲染到canvas上顯示出來
renderer.render(scene, camera);
1.4 加入立方體
要建立一個立方體,我們需要一個BoxGeometry(立方體)物件. 這個物件包含了一個立方體中所有的頂點(vertices)和麵(faces)。
接下來,對於這個立方體,我們需要給它一個材質,來讓它有顏色。這裡我們使用的是MeshBasicMaterial。所有的材質都存有應用於他們的屬性的物件。為了簡單起見,我們只設定一個color屬性,值為0x00ff00,也就是綠色。這裡和CSS或者Photoshop中使用十六進位制(hex colors)顏色格式來設定顏色的方式一致。
第三步,我們需要一個Mesh(網格)。 網格包含一個幾何體以及作用在此幾何體上的材質,我們可以直接將網格物件放入到我們的場景中,並讓它在場景中自由移動。
預設情況下,當我們呼叫scene.add()的時候,物體將會被新增到(0,0,0)座標。但將使得攝像機和立方體彼此在一起。為了防止這種情況的發生,我們只需要將攝像機稍微向外移動一些即可。
// 新增物體
// 建立幾何體
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
// 根據幾何體和材質建立物體
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 將幾何體新增到場景中
scene.add(cube);
2 綜合上述程式碼
1、在前面建立的專案中的main.js檔案寫入程式碼
import * as THREE from "three";
// console.log(THREE);
// 目標:瞭解three.js最基本的內容
// 1、建立場景
const scene = new THREE.Scene();
// 2、建立相機
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 設定相機位置
camera.position.set(0, 0, 10);
scene.add(camera);
// 新增物體
// 建立幾何體
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
// 根據幾何體和材質建立物體
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 將幾何體新增到場景中
scene.add(cube);
// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 設定渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// console.log(renderer);
// 將webgl渲染的canvas內容新增到body
document.body.appendChild(renderer.domElement);
// 使用渲染器,透過相機將場景渲染進來
renderer.render(scene, camera);
效果演示: