3D網頁新手上路 — Babylon.js
👁🗨 初步了解 3D 繪圖套件的使用,創造 Web 3D 空間
Babylon.js 簡述
Babylon.js 是一款基於 WebGL、HTML5 和 JavaScript 即時渲染 3D 引擎,可以通過 HTML5 在 Web 瀏覽器中呈現 3D 模型。由微軟提供完善的開發團隊,文檔完善且更新及時,支持 JavaScript 和 TypeScript 兩種編程語言,相對穩定,因此適合做大型項目。主要多集中用來製作 3D 網頁遊戲,具有碰撞檢測、抗鋸齒等遊戲特性。
目前 Babylon.js 可接受 3D 檔案類型有 gltf、glb、obj、babylon,依據檔案類型差異,取得mesh 變數也會有差異。
使用的 3D 模型可參考這篇文章:如何做出良好的 Babylon.js 模型
使用 Babylon.js 流程
Step 1 :安裝
首先,需要先使用 CDN 引入:
//主程序腳本
<script src="<https://cdn.babylonjs.com/babylon.js>"></script>
//輔助用:加載模型的檔案
<script src="<https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js>"></script>
//輔助用:統一不同瀏覽器上point操作
<script src="<https://code.jquery.com/pep/0.4.3/pep.js>"></script>
或是可以使用 NPM 的方式引入:
npm install babylonjs --saveimport * as BABYLON from 'babylonjs';
Step 2 :創建 BABYLON 引擎
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);// 當頁面被調整時,引擎也會跟著調整
window.addEventListener("resize", function () {
engine.resize();
});
Step 3:建立場景
當完成引入以及創建引擎後,我們就可以來建立 3D 場景,使用 createScene() 函數生成場景,場景就像是搭建一個舞台(如果有用過 pixi.js ,就像是 pixi.js 中的 stage 一樣)。
const createScene = function() {
var scene = new BABYLON.Scene(engine);
return scene;
}const sceneToRender = createScene();// 預設不會轉譯場景,若要在每個畫面上重複轉譯場景,則需要執行以下程式碼:
engine.runRenderLoop(function () {
sceneToRender.render();
});
Step 4:新增攝影機
3D 的空間中,我們需要建立攝影機來顯示出畫面,Babylon 有提供不同種的攝影機,可依照所想要的功能來選擇,這邊列舉兩種最常使用的攝影機(想看更多可以參考官方文件):
📷 Universal Camera
- 通常用來作為第一人稱視角的攝影機,操作適用於所有鍵盤、鼠標、觸控和遊戲手柄。
- 2.3版本後新增,可代替自由相機(Free Camera)、觸控相機(Touch Camera)和遊戲手柄相機(Gamepad Camera)。
- 參數:name(攝影機名稱),position(攝影機初始位置),scene(攝影機位於的場景)
//參數: name, position, scene
const camera = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene);
//設定相機朝向的目標
camera.setTarget(BABYLON.Vector3.Zero());
//設定控制畫布
camera.attachControl(canvas, true);
📷 Arc Rotate Camera
- 攝影機固定指向一個目標位置,旋轉圍繞依照目標來移動。
- 參數:name(攝影機名稱),Alpha(縱軸旋轉角度),Beta(橫軸旋轉角度),radius(半徑),target position(目標位置),scene(攝影機位於的場景)
- 參數中的 Alpha、Beta、radius 的概念,可以參照下圖說明,可以比較理解數值的意思 👇👇👇
//參數: name, alpha, beta, radius, target position, scene
const camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);
//設定攝影機的位置
camera.setPosition(new BABYLON.Vector3(0, 0, 20));
//設定控制畫布
camera.attachControl(canvas, true);
Step 5:新增光源
架設好攝影機之後,需要再添加光源,否則看到的任何物體都會是黑色的,如同人在現實環境中,也是需要有光才有辦法看到物體的顏色,而在 Babylon 中總共有四種光源可以使用。
💡 點光源(BABYLON.PointLight)
- 參數:name,position(場景中的光源位置),scene
- 類似燈泡光源,照在平面上會有點的效果。
const light = new BABYLON.PointLight("pointLight", new BABYLON.Vector3(1, 10, 1), scene)
💡 方向光(BABYLON.DirectionalLight)
- 參數:name,direction(光源照射方向),scene
- 模擬從遠方照過來的光,例如太陽光。
const light = new BABYLON.DirectionalLight("DirectionalLight", new BABYLON.Vector3(0, -1, 0), scene);
💡 聚光燈(BABYLON.SpotLight)
- 參數:name,position(場景中的光源位置),direction(光源照射方向),angle(照射的角度),exponent(光的衰減指數),scene
- 模擬手電筒、探照燈的光源,將光匯聚到一個地方。
- 角度大小影響聚光程度,角度越大、聚光效果越差、照射區域越大。
- 光的衰減指數越大,衰減越快。
const light = new BABYLON.SpotLight("spotLight", new BABYLON.Vector3(0, 30, -10), new BABYLON.Vector3(0, -1, 0), Math.PI / 3, 2, scene);
💡 環境光(BABYLON.HemisphericLight)
- 參數:name,direction(光源的朝向),scene
- 通常設定都是朝向天空、向上,也就是
Vector3(0, 1, 0)
。
const light = new BABYLON.HemisphericLight("HemiLight", new BABYLON.Vector3(0, 1, 0), scene);
光源可以不只一個和一種,可依照需求自行增加。如果需要變更光的顏色,可以使用三個參數進行調整,分別是 diffuse、specular 和 groundColor,顏色設定使用 BABYLON.Color3
調整 RGB,數值位於 0 ~ 1 之間。
- diffuse 代表光的主體顏色(所有光源都有)
- specular 代表照在物體上高亮區域的顏色(所有光源都有)
- groundColor 代表地上反射光的顏色(只有環境光有)
light.diffuse = new BABYLON.Color3(0, 1, 1);
light.specular = new BABYLON.Color3(1, 1, 0);
light.groundColor = new BABYLON.Color3(0, 1, 0);
Step 6:新增 3D 物件
現在我們已經準備好舞台、攝影機和光線,接下來就輪到主角登場了!所謂的「主角」指的是我們要在場景中放置的物件,BABYLON 中可以建立一些基本圖形,它提供兩種寫法,較新的寫法是使用 BABYLON.MeshBuilder
,options 中的參數使用物件形式帶入:
const mesh = BABYLON.MeshBuilder.Create<MeshType>(name, options, scene);
另一種較舊的寫法則是使用 BABYLON.Mesh
,後面的參數則依照建立的圖形不同,按照不同的順序帶入:
const mesh = BABYLON.Mesh.Create<MeshType>(name, required_param1, required_param2, ..., scene, optional_parameter1, ........);
舉例來說,我們要建立一個簡單的球形和地板:
//BABYLON.MeshBuilder
const sphere = BABYLON.MeshBuilder.CreateSphere('sphere1', { segments: 16,diameter: 1.5, }, scene);
const ground = BABYLON.MeshBuilder.CreateGround('ground1', { width: 6, height: 6 , subdivisions: 2}, scene);
ground.position.y = -1;//BABYLON.Mesh
const sphere = BABYLON.Mesh.CreateSphere('sphere1', 16, 1.5, scene);
const ground = BABYLON.Mesh.CreateGround('ground1', 6, 6, 2, scene);
ground.position.y = -1;
目前兩種方式都可以使用,就個人經驗來說,舊的寫法雖然簡潔,但在調整參數時會需要較熟悉參數順序。
若是需要調整材質顏色的話,則使用以下程式碼:
const Material = new BABYLON.StandardMaterial("material", scene);
Material.diffuseColor = BABYLON.Color3.Random(); //球會換成隨機顏色
sphere.material = Material;
除了內建幾何圖形外,我們也可以引入自己的 3D 模型使用,引入的方式是使用 SceneLoader
(❗記得前面要先引用 CDN),而在 SceneLoader
中又可細分出幾個引入的函式,這次先針對 ImportMeshAsync
說明,其他的詳細內容可參考官方說明。
先載入一個 Totoro 的模型,並試著將載入後的資訊 log 出來:
//參數:model name, folder path, file name, scene
BABYLON.SceneLoader.ImportMeshAsync('', "./", "Totoro.glb", scene)
.then((_scene) => {
console.log(_scene);
});
一般來說,建議使用的模型檔案格式為 glb,若是使用 obj 或是其他格式等等,可能就比較不好抓取整個模型,因為 glb 的第一層 Mesh 都會是根目錄 root,因此我們可以藉由取得根目錄調整模型的大小或位置。
//參數:model name, folder path, file name, scene
BABYLON.SceneLoader.ImportMeshAsync('', "./", "Totoro.glb", scene)
.then((_scene) => {
console.log(_scene);
const root = _scene.meshes[0]; //取得整個模型的mesh
root.normalizeToUnitCube(); //初始化大小和位置
root.position.set(0, 0, 0); //設定位置
root.scaling.scaleInPlace(1.5); //設定大小為1.5倍
});
登登!以下為示範畫面:
從 Step1 ~ Step6 一步一步寫下來,舞台、燈光、攝影機以及角色,把握這幾個大原則,就能完成簡單的 3D 場景。不過,本篇是以靜態模型為主,若是需要讓使用者與畫面互動或是撥放 3D 動畫,則要再參考官方文件中的函式庫,並且調整其中的細節參數,以及需要使用動畫模型或是骨架等等,細節過多就不寫在本篇中🙇♀️。
參考:
https://www.babylonjs.com/
https://www.hellodemos.com/hello-babylonjs/babylonjs-playground.html
https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/746049/
https://www.jianshu.com/p/4e266bef778f
https://docs.microsoft.com/zh-tw/windows/mixed-reality/develop/javascript/tutorials/babylonjs-webxr-helloworld/prepare-scene-02
https://www.tutorialspoint.com/babylonjs/babylonjs_lights.htm
https://medium.com/%E9%BB%91%E6%B4%9E%E5%89%B5%E9%80%A0-blackhole-creative/%E5%A6%82%E4%BD%95%E5%81%9A%E5%87%BA%E8%89%AF%E5%A5%BD%E7%9A%84-babylon-js-%E6%A8%A1%E5%9E%8B-16096c6faf2c