超越 Three.js? Babylon.js 將成為構(gòu)建元宇宙重要工具?

哈嘍,大家好 我是xy???????。構(gòu)建 3D 場(chǎng)景,也許大家第一個(gè)想到的可能是 Threejs, 那么今天就來(lái)給大家推薦另外一個(gè)庫(kù),Babylon.js , 它將會(huì)變成構(gòu)建元宇宙重要工具之一



上圖就是官方的案例之一,是不是很炫酷,以下就來(lái)給大家簡(jiǎn)單介紹下 Babylon.js 的使用

babylon.js 是什么?
Babylon.js 是一個(gè)非常簡(jiǎn)單的 JavaScript API,微軟旗下 WebGL 框架, 對(duì)所有開發(fā)人員都非常友好,它的意義就是簡(jiǎn)化開發(fā)流程,讓更多 Web 開發(fā)者能夠在自己的應(yīng)用程序中利用 GPU 資源。用于構(gòu)建 HTML5,WebGL,WebVR 和 Web Audio 的 3D 游戲和體驗(yàn). 除了游戲, 用來(lái)在頁(yè)面實(shí)現(xiàn)一些 3D 場(chǎng)景也是沒(méi)問(wèn)題的

安裝 Babylon.js
npm install --save babylonjs
這將安裝 babylonjs 的 javascript 文件,還將包含 TypeScript 聲明文件。

要在 ts 文件中聲明,請(qǐng)使用:

import * as BABYLON from 'babylonjs';
創(chuàng)建場(chǎng)景
 <script>
  // 創(chuàng)建畫布
 var canvas = document.getElementById("show1");
  // 創(chuàng)建渲染引擎
 var engine = new BABYLON.Engine(canvas, true);
  // 創(chuàng)建一個(gè)場(chǎng)景并返回
 var create_scene = function(){

 var scene = new BABYLON.Scene(engine);
 /* 創(chuàng)建一個(gè)弧形旋轉(zhuǎn)攝像機(jī). 參數(shù)說(shuō)明如下:
 * "Camera": 攝像機(jī)名稱
 * 第一個(gè) Math.PI / 2 : alpha, 可以理解為水平角度.具體請(qǐng)看文檔
 * 第二個(gè) Math.PI / 2 : beta, 可以理解為垂直角度.具體請(qǐng)看文檔
 * 2: radius, 這個(gè)是半徑的意思.
 * new BABYLON.Vector3(0, 0, 5) : target position.目標(biāo)點(diǎn)的三維位置,可以理解為中心.這是一個(gè)向量類的實(shí)例
 * scene: scene,場(chǎng)景變量.
 * 詳細(xì)文檔請(qǐng)看這里: 看著圖比較好理解的.https://doc.babylonjs.com/babylon101/cameras#arc-rotate-camera
 */

 var camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new BABYLON.Vector3(0, 0, 5), scene);

 /* 讓攝像機(jī)控制畫布.
 * canvas: element 是一個(gè)dom對(duì)象.
 * true: noPreventDefault 是否阻止元素的默認(rèn)事件.
 * api: https://doc.babylonjs.com/api/classes/babylon.targetcamera
 */

 camera.attachControl(canvas, true);

 /* 創(chuàng)建2個(gè)光源. HemisphericLight是半球形光源.PointLight是點(diǎn)光源.
 * 第一個(gè)參數(shù): name. 名字.
 * 第二個(gè)參數(shù): direction, 方向,是一個(gè)向量的實(shí)例.
 * 第三個(gè)參數(shù): scene, 場(chǎng)景.
 * api: https://doc.babylonjs.com/api/classes/babylon.hemisphericlight#constructor
 */

 var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 1, 0), scene);
 var light2 = new BABYLON.PointLight("light3", new BABYLON.Vector3(0, 1, -1), scene);

 /* 創(chuàng)建一個(gè)球形的控制網(wǎng)格. options參數(shù),請(qǐng)看api
 * 第一個(gè)參數(shù) name: 字符串, 名字
 * 第二個(gè)參數(shù) options: object, 參數(shù)對(duì)象.
 * 第三個(gè)參數(shù) scene: 場(chǎng)景
 * api: https://doc.babylonjs.com/api/classes/babylon.meshbuilder#createsphere
 */

 var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2}, scene);
 return scene;
 };

 var scene = create_scene();

 /* 不停的渲染場(chǎng)景.
 * runRenderLoop 是一個(gè)渲染循環(huán).
 * api: https://doc.babylonjs.com/api/classes/babylon.engine#runrenderloop
 */

 engine.runRenderLoop(function(){
 scene.render();   // 渲染場(chǎng)景


 });
 window.addEventListener("resize", function(){
 engine.resize();
 });

 </script>
渲染效果展示:



創(chuàng)建基礎(chǔ)模型
1.MeshBuilder 方法
創(chuàng)建模型的方法一般是:

var shape = BABYLON.MeshBuilder.Create Shape(名稱,配置項(xiàng),場(chǎng)景);
配置項(xiàng)的參數(shù)允許你設(shè)置形狀大小以及是否可以更新它之類的操作。

2.創(chuàng)建立方體
創(chuàng)建一個(gè)默認(rèn)的立方體

var box = BABYLON.MeshBuilder.CreateBox("box", {}, scene);





創(chuàng)建一個(gè)帶有配置項(xiàng)的立方體

var myBox = BABYLON.MeshBuilder.CreateBox("myBox", {height: 5, width: 2, depth: 0.5}, scene);
size (number)每個(gè)邊的長(zhǎng)度
height (number)立方體的高度
width (number)立方體的寬度
depth (number)立方體的深度
faceColors (Color4[])六個(gè)顏色對(duì)象組成的數(shù)組,每個(gè)顏色代表一個(gè)面的顯示顏色 每個(gè)面默認(rèn) Color(1,1,1,1)
faceUV (Vector4[]) 由六個(gè)四維向量組成的數(shù)組,每個(gè)代表一個(gè)面的 uv 映射 每個(gè)面的 uv 映射從 0,0 到 1,1
updatable (boolean)如果網(wǎng)格是可更新的,則設(shè)置為 true false
sideOrientation (number)面的顯示方向 DEFAULTSIDE
3.創(chuàng)建球體
var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {}, scene); //默認(rèn)的球體
創(chuàng)建一個(gè)設(shè)置配置項(xiàng)的球體

var mySphere = BABYLON.MeshBuilder.CreateSphere("mySphere", {diameter: 2}, scene);
segments (number)水平的分段數(shù)
diameter (number)球體的直徑
diameterX (number)X 軸上的球的直徑 diameter
diameterY (number) Y 軸上的直徑 diameter
diameterZ (number)Z 軸上的直徑 diameter
arc (number)沿緯度線顯示區(qū)域 值介于 0 到 1 1
slice (number)沿經(jīng)度繪制顯示 值介于 0 到 1 1
updatable (boolean)如果網(wǎng)格是可更新的,則設(shè)置為 true false
sideOrientation (number)面的顯示方向 DEFAULTSIDE
4.創(chuàng)建平面
var plane = BABYLON.MeshBuilder.CreatePlane("plane", {}, scene);
創(chuàng)建一個(gè)帶有配置項(xiàng)的平面

var myPlane = BABYLON.MeshBuilder.CreatePlane("myPlane", {width: 5, height: 2}, scene);
size (number)平面每個(gè)邊的長(zhǎng)度
height (number)平面的高度
width (number)平面的寬度
updatable (boolean)如果網(wǎng)格是可更新的,則設(shè)置為 true false
sideOrientation (number)面的顯示方向 DEFAULTSIDE
frontUVs (Vector4[])正面 UV 映射,只有在 sideOrientation 設(shè)置為雙面(BABYLON.Mesh.DOUBLESIDE)時(shí)使用 Vector4(0,0,1,1)
backUVs (Vector4[])背面 UV 映射,只有在 sideOrientation 設(shè)置為雙面(BABYLON.Mesh.DOUBLESIDE)時(shí)使用 Vector4(0,0,1,1)
sourcePlane (Plane)這是數(shù)學(xué)平面,用于修改平面網(wǎng)格的位置朝向 空值
sourcePlane 是一個(gè)平面網(wǎng)格的獨(dú)特選擇,它提供了一種方法來(lái)定向和定位它。
現(xiàn)在只考慮它的方向在創(chuàng)建上是矢量(0,0,1)現(xiàn)在你要讓方向成為矢量(0,1,1)然后你用它來(lái)創(chuàng)建一個(gè)源平面

var sourcePlane = new BABYLON.Plane(0,0,1,0);
這就創(chuàng)建了一個(gè)數(shù)學(xué)平面,它被用作定位源。第四個(gè)參數(shù)是向方向矢量方向移動(dòng)的距離。這里暫時(shí)設(shè)為 0。

5.創(chuàng)建地面
var ground = BABYLON.MeshBuilder.CreateGround("ground", {}, scene);
創(chuàng)建一個(gè)自定義的地面

var myGround = BABYLON.MeshBuilder.CreateGround("myGround", {width: 6, height: 4}, scene);
size (number)地面每個(gè)邊的長(zhǎng)度
height (number)地面的高度
width (number)地面的寬度
updatable (boolean)如果網(wǎng)格是可更新的,則設(shè)置為 true false
subdivisions (number)將地面分成幾塊



創(chuàng)建天空影像
所謂的天空盒其實(shí)就是將一個(gè)立方體展開,然后在六個(gè)面上貼上相應(yīng)的貼圖

在實(shí)際的渲染中,將這個(gè)立方體始終罩在攝像機(jī)的周圍,讓攝像機(jī)始終處于這個(gè)立方體的中心位置,然后根據(jù)視線與立方體的交點(diǎn)的坐標(biāo),來(lái)確定究竟要在哪一個(gè)面上進(jìn)行紋理采樣。具體的映射方法為:設(shè)視線與立方體的交點(diǎn)為(x,y,z)(x,y,z),在 x、y、zx、y、z 中取絕對(duì)值最大的那個(gè)分量,根據(jù)它的符號(hào)來(lái)判定在哪個(gè)面上采樣。

每個(gè)圖像的名稱應(yīng)有一個(gè)共同的部分,后跟一個(gè)由_px,_nx,_py,_ny,_pz 或_nz 給出的位置,分別對(duì)應(yīng)于 x,y 或 z 軸的正(p)或負(fù)(n)

var createScene = function () {
    var scene = new BABYLON.Scene(engine);
    var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 2,  Math.PI / 2, 5, BABYLON.Vector3.Zero(), scene);
    camera.attachControl(canvas, true);

 var light = new BABYLON.HemisphericLight("hemiLight", new BABYLON.Vector3(-1, 1, 0), scene);
 light.diffuse = new BABYLON.Color3(1, 0, 0);

 // Skybox
 var skybox = BABYLON.MeshBuilder.CreateBox("skyBox", {size:1000.0}, scene);
 var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);
 skyboxMaterial.backFaceCulling = false;
 skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("textures/skybox", scene);
 skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
 skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
 skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
 skybox.material = skyboxMaterial;

    return scene;

};
渲染效果展示:




作者:前端小菜雞之菜雞互啄


歡迎關(guān)注微信公眾號(hào) :前端開發(fā)愛(ài)好者


添加好友備注【進(jìn)階學(xué)習(xí)】拉你進(jìn)技術(shù)交流群