BabylonJS 快速指南



BabylonJS - 簡介

Babylon.js 是一個用於開發 Web 端 3D 應用/影片遊戲的開源 JavaScript 框架。BabylonJS 的官方網站是 www.babylonjs.com

使用 Babylon.js 框架對使用者來說很容易。它包含建立和管理 3D 物件、特效和聲音等所需的所有工具。

Babylon.js 是最流行的 3D 遊戲引擎之一,被廣泛用於開發者。作為一個 3D 庫,它提供內建函式。這些函式幫助你以高效和準確的方式實現常見的 3D 功能。

它使用基於 WebGL 和 JavaScript 的 TypeScript 語言開發。

什麼是 WebGL?

WebGL(Web 圖形庫)是 Web 上 3D 圖形的最新標準。它旨在用於渲染 2D 圖形和互動式 3D 圖形。它源自 OpenGL ES 2.0 庫,這是一個針對手機和其他移動裝置的低階 3D API。WebGL 提供與 ES 2.0(嵌入式系統)類似的功能,並在現代 3D 圖形硬體上表現良好。

TypeScript

根據定義,“TypeScript 是用於應用程式規模開發的 JavaScript”。

TypeScript 是一種強型別、面向物件、編譯型語言。TypeScript 既是一種語言,也是一組工具。TypeScript 是 JavaScript 的型別超集,編譯成 JavaScript。換句話說,TypeScript 是 JavaScript 加上一些附加功能。

TypeScript 語言的目標是改進和確保 JavaScript 程式碼的生產。由於 BabylonJS 使用 TypeScript 開發,因此它具有健壯性和安全性。

BabylonJS - 環境搭建

在本章中,我們將學習如何為 BabylonJS 設定環境。

首先,訪問 Babylon.js 的官方網站:www.babylonjs.com。轉到下載部分,選擇最新版本的 Babylon.js 並將其儲存在您的資料夾中。

相應的截圖如下:

BabylonJS Website Screenshot

你也可以去 GITHUB 並克隆 babylonjs 專案:

Babylon.js

在你的命令列中輸入:

git clone https://github.com/BabylonJS/Babylon.js.git
go to cd BabylonJS/
npm install

所需的文將會在 BabylonJS 資料夾中。

您可以使用 VSCode(Microsoft Visual Studio Code)進行編輯。程式碼具有內建功能,例如突出顯示任何錯誤、突出顯示語法等。您可以使用您選擇的編輯器,並且不必強制使用 VSCode。

BabylonJS - 概述

BabylonJS 是一個使用 HTML5 和 WebGL 構建 3D 遊戲的開源 JavaScript 框架。它託管在 github 上。BabylonJS 的官方網站是 www.babylonjs.com

在 3D 動畫的世界中,形狀是用三角形繪製的。使用 WebGL,編碼過程的複雜性會隨著程式碼量的增加而增加。BabylonJS 是一個簡單的解決方案,可以幫助減輕增加的複雜性。在這裡,燈光、相機、引擎的 API 易於處理和建立 3D 物件。

babylonJS 的原始碼是用 typescript 編寫的。它被編譯成 Javascript 並提供給終端使用者。

要開始使用 Babylonjs,請下載 babylonjs 檔案,在您的端託管它,然後您就可以開始編寫您的 3D 程式碼了。

BabylonJS 由微軟員工於 2016 年開發。微軟 Windows 和裝置部門的首席專案經理 David Catuhe 是 BabylonJs 開發和取得巨大成功的主要負責人。

要執行 BabylonJS,我們需要支援 WebGL 的現代瀏覽器。最新的瀏覽器,即 Internet Explorer 11+、Firefox 4+、Google Chrome 9+、Opera 15+ 等都支援 WebGL,演示可以在同一平臺上執行以檢視輸出。

BabylonJs 提供以下功能,有助於建立不同型別的 3D 場景:

  • 形狀,如盒子、球體、圓柱體、錐體、高度地面
  • 相機、燈光
  • 網格、紋理、材質
  • 精靈
  • 變形
  • 網格相交和碰撞檢測
  • 物理引擎外掛
  • 動作管理器
  • SolidParticles
  • 例項和粒子
  • 支援骨骼和骨架
  • 向場景新增音樂和聲音

除了它自己的網格之外,BabylonJS 還允許使用從 Blender、FBX 和 3DS Max 等第三方 3D 軟體建立的網格。

Blender

Blender 是一款開源的 3D 計算機圖形軟體產品,用於建立動畫場景、3D 列印模型、影片遊戲等。Blender 提供 babylon 檔案,這些檔案將與 Babylon 一起用於渲染網格。本教程後續章節將解釋如何將 Blender 檔案轉換為 babylon 檔案。

FBX

也稱為 filmbox,它有助於 3D 動畫和紋理繪畫軟體。FBX 檔案以 .fbx 副檔名儲存。

MAX

MAX 軟體可以幫助您在遊戲中建立龐大的世界、為設計建立令人驚歎的場景以及引人入勝的虛擬現實體驗。

BabylonJS - 基本元素

Babylon.js 是一個流行的框架,可以幫助開發者構建 3D 遊戲。它具有內建函式來實現 3D 功能。讓我們使用 Babylon.js 構建一個簡單的演示,並瞭解入門所需的基本功能。

我們將首先建立一個包含 Babylon.js 基本元素的演示。此外,我們還將學習 Babylon.js 的各種功能。

示例演示 1

在本節中,我們將學習如何建立一個包含 BabylonJS 基本元素的演示。

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title> Babylon.JS : Demo2</title>
      <script src = "babylon.js"></script>
      <style>
         canvas { width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 0.8, 0.8);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            scene.activeCamera.attachControl(canvas);
            
            var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 0, 10), scene);
            
            var origin = BABYLON.Mesh.CreateSphere("origin", 10, 1.0, scene);
            
            var torus = BABYLON.Mesh.CreateTorus("torus", 5, 1, 10, scene, false);
            
            var box = BABYLON.Mesh.CreateBox("box", 3.0, scene);
            box.position = new BABYLON.Vector3(-5, 0, 0); 
            
            var cylinder = BABYLON.Mesh.CreateCylinder("cylinder", 3, 3, 3, 6, 1, scene, false);
            
            cylinder.position = new BABYLON.Vector3(5, 0, 0);	
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>
Babylonjs Basic Elements

要執行 BabylonJS,我們需要支援 WebGL 的現代瀏覽器。最新的瀏覽器 - Internet Explorer 11+、Firefox 4+、Google Chrome 9+、Opera 15+ 等都支援 WebGL,演示可以在相同的平臺上執行以檢視輸出。建立一個目錄來儲存 babylonjs 的檔案。從 BabylonJS 網站獲取最新的 BabylonJS 指令碼檔案。本教程中的所有演示連結都使用 babylonjs 3.3 版本進行了測試。

步驟 1

  • 建立一個簡單的 html 頁面幷包含 Babylon.js 檔案。

  • 建立一個 canvas 標籤,BabylonJS 用於在 body 標籤內渲染內容,如下所示。

  • 向 canvas 新增 css 以佔據螢幕的全部寬度和高度。

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>MDN Games: Babylon.js demo - shapes</title>
      <script src = "babylon.js"></script>
      
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   <body>
      <canvas id = "renderCanvas"></canvas>
   </body>
</html>

步驟 2

現在讓我們開始使用 BabylonJS 程式碼在畫布上渲染內容。

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>MDN Games: Babylon.js demo - shapes</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
      </script>
   </body>
</html>

現在,將指令碼標籤新增到 html 結構中,並將畫布引用儲存在變數 canvas 中。

要開始使用 Babylon.js,請建立一個引擎例項並將畫布引用傳遞給它以進行渲染。

<script type = "text/javascript">
   var canvas = document.getElementById("renderCanvas");
   var engine = new BABYLON.Engine(canvas, true);
</script>

BABYLON 全域性物件包含引擎中可用的所有 Babylon.js 函式。

步驟 3

在此步驟中,我們將首先建立一個場景。

場景是所有內容將顯示的地方。我們將建立不同型別的物件並將它們新增到場景中,使其在螢幕上可見。要建立場景,請將以下程式碼新增到已建立的 html 結構中。目前,我們將把它作為對上面 html 結構的延續新增到已建立的程式碼中。

var createScene  = function() {
   var scene = new BABYLON.Scene(engine);
   scene.clearColor = new BABYLON.Color3(1, 0.8, 0.8);
};
var scene = createScene();

最終的 html 檔案如下所示:

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>MDN Games: Babylon.js demo - shapes</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            return scene;
         };
         var scene = createScene();
      </script>
   </body>
</html>

在上面的示例中,定義了 CreateScene 函式,而 var scene = createScene() 正在呼叫該函式。

CreateScene 函式在其內部建立了場景,下一行使用 BABYLON.Color3(1, 0.8, 0.8) 為場景新增顏色,這裡的顏色是粉紅色。

var scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3(1, 0.8, 0.8);

目前在瀏覽器中執行上述演示連結不會在瀏覽器螢幕上顯示任何內容。還需要向程式碼中新增一個步驟,即 engine.runRenderLoop,如步驟 4 所示。

步驟 4

要使場景實際在螢幕上可見,我們需要使用 engine.runRenderLoop 呼叫來渲染它。現在讓我們看看這是如何完成的。

渲染迴圈

engine.runRenderLoop(function() {
   scene.render();
});

Engine.runRenderLoop 函式呼叫 scene.render,這將渲染場景並使其對使用者可見。最終的 .html 檔案如下所示:

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 0.8, 0.8);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

將上述檔案儲存為 basicscene.html 並檢查瀏覽器中的輸出。顯示的螢幕為粉紅色,如下所示:

Pink Output Browser Screen

步驟 5

現在我們有了場景,我們必須向其中新增相機。

新增相機和燈光

下面給出的程式碼將相機新增到場景中。Babylon 中可以使用許多型別的相機。

ArcRotateCamera 是一種圍繞目標旋轉的相機。它可以使用滑鼠、游標或觸控事件進行控制。所需的引數是名稱、alpha、beta、radius、target 和 scene。我們將在後續部分討論相機的詳細資訊。

var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);

現在,我們需要了解如何新增燈光。

燈光用於產生每個畫素接收到的漫射和鏡面顏色。有許多型別的燈光。我們將在燈光部分學習不同型別的燈光。

這裡我在場景中使用 PointLight。PointLight 像太陽一樣向各個方向發射。引數是名稱、位置和要使用的場景。

要新增燈光,請執行以下程式碼:

var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 0, 10), scene);

步驟 6

現在讓我們看看如何新增形狀。

新增形狀

上面共享的演示添加了 4 個形狀。

  • 球體
  • 環面
  • 盒子
  • 圓柱體

要新增球體,請執行以下程式碼:

var origin = BABYLON.Mesh.CreateSphere("origin", 10, 1.0, scene);

新增球體後,程式碼如下所示:

<!doctype html>
<html>
   <head>
      <meta charset="utf-8">
      <title>MDN Games: Babylon.js demo - shapes</title>
      <script src = "babylon.js"></script>
      <style>
         html,body,canvas { margin: 0; padding: 0; width: 100%; height: 100%; font-size: 0; }
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 0.8, 0.8);
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 0, 10), scene);
            var origin = BABYLON.Mesh.CreateSphere("origin", 10, 1.0, scene);
            scene.activeCamera.attachControl(canvas);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼生成以下輸出:

Scenesphere

現在讓我們新增其他形狀 - 環面和盒子。執行以下程式碼以新增環面形狀。

var torus = BABYLON.Mesh.CreateTorus("torus", 5, 1, 10, scene, false);
var box = BABYLON.Mesh.CreateBox("box", 3.0, scene);
box.position = new BABYLON.Vector3(-5, 0, 0);

我們將向盒子新增一個位置。BABYLON.Vector3(-5, 0, 0) 獲取 x、y 和 z 方向。

執行後,上述程式碼生成以下輸出:

Torus shape

現在讓我們新增上圖截圖中顯示的最終形狀 - 圓柱體。

var cylinder = BABYLON.Mesh.CreateCylinder("cylinder", 3, 3, 3, 6, 1, scene, false);
cylinder.position = new BABYLON.Vector3(5, 0, 0);

位置被新增到圓柱體,它是 x 方向 5。最終程式碼如下所示:

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title> Babylon.JS : Demo2</title>
      <script src = "babylon.js"></script>
      <style>
         canvas { width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 0.8, 0.8);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            scene.activeCamera.attachControl(canvas);
            
            var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 0, 10), scene);
            
            var origin = BABYLON.Mesh.CreateSphere("origin", 10, 1.0, scene);
            
            var torus = BABYLON.Mesh.CreateTorus("torus", 5, 1, 10, scene, false);
            
            var box = BABYLON.Mesh.CreateBox("box", 3.0, scene);
            box.position = new BABYLON.Vector3(-5, 0, 0); 
            
            var cylinder = BABYLON.Mesh.CreateCylinder("cylinder", 3, 3, 3, 6, 1, scene, false);
            cylinder.position = new BABYLON.Vector3(5, 0, 0);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

執行後,上述程式碼將生成以下輸出:

Basic Elements shapes

形狀將根據您移動游標的方向移動;這是透過將相機的附加控制元件附加到場景來完成的。

scene.activeCamera.attachControl(canvas);

現在讓我們詳細討論每個形狀。

以下是所有形狀和語法的摘要:

序號 形狀 語法
1 盒子
var box = BABYLON.Mesh.CreateBox(
   "box", 6.0, scene, false, BABYLON.Mesh.DEFAULTSIDE);
2 球體
var sphere = BABYLON.Mesh.CreateSphere(
   "sphere", 10.0, 10.0, scene, 
   false, BABYLON.Mesh.DEFAULTSIDE);
3 平面
var plane = BABYLON.Mesh.CreatePlane(
   "plane", 10.0, scene, false, BABYLON.Mesh.DEFAULTSIDE);
4 圓盤
var disc = BABYLON.Mesh.CreateDisc(
   "disc", 5, 30, scene, false, BABYLON.Mesh.DEFAULTSIDE);
5 圓柱體
var cylinder = BABYLON.Mesh.CreateCylinder(
   "cylinder", 3, 3, 3, 6, 1, scene, false, 
   BABYLON.Mesh.DEFAULTSIDE);
6 環面
var torus = BABYLON.Mesh.CreateTorus(
   "torus", 5, 1, 10, scene, false, 
   BABYLON.Mesh.DEFAULTSIDE);
7 紐結
var knot = BABYLON.Mesh.CreateTorusKnot(
   "knot", 2, 0.5, 128, 64, 2, 3, scene, false, 
   BABYLON.Mesh.DEFAULTSIDE);
8 線網格
var lines = BABYLON.Mesh.CreateLines("lines", [
   new BABYLON.Vector3(-10, 0, 0),
   new BABYLON.Vector3(10, 0, 0),
   new BABYLON.Vector3(0, 0, -10),
   new BABYLON.Vector3(0, 0, 10)
], scene);
9 虛線
var dashedlines = BABYLON.Mesh.CreateDashedLines(
   "dashedLines", [v1, v2, ... vn], 
   dashSize, gapSize, dashNb, scene);
10 飄帶
var ribbon = BABYLON.Mesh.CreateRibbon(
   "ribbon", 
   [path1, path2, ..., pathn], 
   false, false, 0, 
   scene, false, 
   BABYLON.Mesh.DEFAULTSIDE);
11
var tube = BABYLON.Mesh.CreateTube(
   "tube", 
   [V1, V2, ..., Vn], 
   radius, tesselation, 
   radiusFunction, 
   cap, scene, false, 
   BABYLON.Mesh.DEFAULTSIDE);
12 地面
var ground = BABYLON.Mesh.CreateGround(
   "ground", 6, 6, 2, scene);
13 來自高度圖的地面
var ground = BABYLON.Mesh.CreateGroundFromHeightMap(
   "ground", "heightmap.jpg", 200, 200, 250, 0, 10, 
   scene, false, successCallback);
14 平鋪地面
var precision = {"w" : 2, "h" : 2};
var subdivisions = {'h' : 8, 'w' : 8};
var tiledGround = BABYLON.Mesh.CreateTiledGround(
   "Tiled Ground", -3, -3, 3, 3, 
   subdivisions, precision, scene, false);

基本元素 - 位置、旋轉和縮放

在本節中,我們將學習如何定位、旋轉或縮放到目前為止我們新增的元素。

我們建立了盒子、球體、圓柱體、紐結等。現在,我們將看到如何定位、縮放和旋轉形狀。

序號。 元素及描述
1 位置

改變位置時,網格將從一個位置變換到另一個位置。

2 旋轉

旋轉時,網格將圍繞自身旋轉。

3 縮放

網格的縮放可以相對於x、y或z軸進行。

基本元素 - 父子關係

使用父子關係,我們將建立網格之間的父子關係,並觀察它們的行為。因此,你對父物件應用的任何變換,也將應用於子物件。讓我們透過下面的演示來了解這一點。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
         
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            scene.activeCamera.attachControl(canvas);
         
            var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 100, 100), scene);

            var boxa = BABYLON.Mesh.CreateBox("BoxA", 1.0, scene);
            boxa.position = new BABYLON.Vector3(0,0.5,0);

            var boxb = BABYLON.Mesh.CreateBox("BoxB", 1.0, scene);
            boxb.position = new BABYLON.Vector3(3,0.5,0);		
            boxb.scaling = new BABYLON.Vector3(2,1,2);

            var boxc = BABYLON.Mesh.CreateBox("BoxC", 1.0, scene);
            boxc.parent = boxb;
            boxc.position.z = -3;
         
            var ground = BABYLON.Mesh.CreateGround("ground1", 10, 6, 2, scene);
            ground.position = new BABYLON.Vector3(0,0,0);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Basic Element Parenting

解釋

我們在上面的網格中建立了3個盒子。在演示中,應用了boxb的縮放,並將其設定為boxc的父物件,由於其父物件boxb也進行了縮放,因此boxc也會縮放。你可以使用演示來檢視父子連結是如何工作的。

要建立網格,你必須使用另一個網格的父物件:

  • child.parent = parentmesh;

基本元素 - 環境

在本節中,讓我們討論場景環境。我們將討論場景中的場景背景顏色、環境色、天空盒、霧模式等。

我們已經看到了我們目前為止建立的場景背景顏色演示

場景背景顏色

讓我們看看場景背景顏色是如何工作的。

語法

以下是場景背景顏色的語法:

scene.clearColor = new BABYLON.Color3(0.5, 0.8, 0.5);
or
scene.clearColor = BABYLON.Color3.Blue();

上述屬性將更改場景的背景顏色。

場景環境色

讓我們看看場景環境色是如何工作的。

語法

以下是場景環境色的語法:

scene.ambientColor = new BABYLON.Color3(0.3, 0.3, 0.3);

AmbientColor與StandardMaterial的環境色和紋理一起使用。如果場景沒有ambientColor,則StandardMaterial.ambientColorStandardMaterial.ambientTexture無效。一旦應用了場景的ambientColor,StandardMaterial環境色/環境紋理將被啟用。預設情況下,場景的scene.ambientColor設定為Color3 (0, 0, 0),這意味著沒有環境色。

場景霧模式

我們現在將瞭解場景霧模式是如何工作的。

語法

以下是場景霧模式的語法。

scene.fogMode = BABYLON.Scene.FOGMODE_EXP;

以下是可用的霧模式列表:

  • BABYLON.Scene.FOGMODE_NONE - 預設值,霧被停用。

  • BABYLON.Scene.FOGMODE_EXP - 霧密度遵循指數函式。

  • BABYLON.Scene.FOGMODE_EXP2 - 與上面相同,但速度更快。

  • BABYLON.Scene.FOGMODE_LINEAR - 霧密度遵循線性函式。

如果定義了霧模式EXP或EXP2,則可以如下定義其密度:

scene.fogDensity = 0.01;

如果霧模式為LINEAR,則可以如下定義霧的起始和結束位置:

scene.fogStart = 20.0;
scene.fogEnd = 60.0;

要為霧著色,請執行以下程式碼:

scene.fogColor = new BABYLON.Color3(0.9, 0.9, 0.85);

天空盒

天空盒是在遊戲中建立背景的一種方法,它使場景看起來更逼真。它更像是你螢幕周圍的一個包裝器,用作材質的紋理覆蓋它。選擇合適的影像,以使你想要建立的場景看起來更逼真。要建立天空盒,你必須建立一個盒子並應用材質。我們將在後續章節中詳細討論不同的材質。

現在,我們將看到如何使用盒子和材質建立天空盒。

var skybox = BABYLON.Mesh.CreateBox("skyBox", 100.0, scene);

我們將建立一個大小為100的盒子,以便它覆蓋整個場景。我們將首先為盒子賦予材質,操作如下:

var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);

我們將為此材質分配屬性。

skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("images/cubetexture/skybox", scene);

我們必須使用反射紋理,它基本上用於建立類似鏡子的材質。反射紋理屬性使用CubeTexture,它以影像作為輸入。由於立方體有6個面,因此天空盒所需的影像必須是6個,即內部必須儲存為skybox_nx、skybox_ny、skybox_nz、skybox_px、skybox_py、skybox_pz。用於天空盒的影像貼上在下面;它們是立方體六個面上所有面的影像。當你將紋理應用於形狀時,它會提供所用影像的細節,並使場景看起來更逼真。我們使用了SKYBOX_MODE作為座標模式,如下所示:

skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;

材質還使用了其他屬性,例如backfaceCulling、diffuseColor、specularColor、disableLighting等。這些屬性將在材質部分詳細解釋。

在演示中,我們將展示一個使用天空盒建立的環境場景,其中一個球體在場景中旋轉,一個平面四處移動。霧被應用於場景,當你旋轉時你會注意到。

演示環境場景

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title> Babylon.JS : Demo</title>
      <script src = "babylon.js"></script>
      <style>
         canvas { width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            var light = new BABYLON.PointLight("Omni", 
            new BABYLON.Vector3(10, 50, 50), scene);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 0.4, 1.2, 20, new BABYLON.Vector3(-10, 0, 0), scene);
            camera.attachControl(canvas, true);

            var material1 = new BABYLON.StandardMaterial("mat1", scene);
            material1.diffuseTexture = new BABYLON.Texture("images/tsphere.jpg", scene);

            var sphere = BABYLON.Mesh.CreateSphere("red", 32, 2, scene);
            sphere.setPivotMatrix(BABYLON.Matrix.Translation(2, 0, 0));
            sphere.material = material1;		

            // Fog
            scene.fogMode = BABYLON.Scene.FOGMODE_EXP;
            scene.fogColor = new BABYLON.Color3(0.9, 0.9, 0.85);
            scene.fogDensity = 0.01;

            //skybox		
            var skybox = BABYLON.Mesh.CreateBox("skyBox", 100.0, scene);
            
            var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);
            skyboxMaterial.backFaceCulling = false;
            
            skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("images/cubetexture/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);
            
            skyboxMaterial.disableLighting = true;
            skybox.material = skyboxMaterial;


            var spriteManagerPlayer = new BABYLON.SpriteManager("playerManager", "images/plane.png", 8, 1000, scene);
            
            var plane = new BABYLON.Sprite("plane", spriteManagerPlayer);
            plane.position.x = -2;
            plane.position.y = 2;	
            plane.position.z = 0;	


            var alpha = 0;
            var x = 2;
            var y = 0;
            scene.registerBeforeRender(function () {
               scene.fogDensity = Math.cos(alpha) / 10;
               alpha += 0.02;
               sphere.rotation.y += 0.01;
               y += 0.05; 
               if (x > 50) {
                  x = -2;
               }
               plane.position.x = -x;
               x += 0.02; 
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Basic Element Skybox Mode

解釋

在上面的示例中,我們使用以下程式碼進行霧化:

scene.fogMode = BABYLON.Scene.FOGMODE_EXP;
scene.fogColor = new BABYLON.Color3(0.9, 0.9, 0.85);
scene.fogDensity = 0.01;
  • scene.fogMode = BABYLON.Scene.FOGMODE_EXP - 在這裡,霧密度遵循指數函式。

  • scene.registerBeforeRender = 透過此方法,霧密度將如下變化:

var alpha = 0;
scene.registerBeforeRender(function () {
   scene.fogDensity = Math.cos(alpha) / 10;
   alpha += 0.02;
});

alpha的值隨著迴圈的進行而以0.02遞增,如上函式所示。

在這裡,我們添加了一個平面精靈影像,並使用scene.registerBeforeRender函式更改其位置,如下所示:

var alpha = 0;
var x = 2;
var y = 0;
scene.registerBeforeRender(function () {
   scene.fogDensity = Math.cos(alpha) / 10;
   alpha += 0.02;
   sphere.rotation.y += 0.01;
   y += 0.05; 
   if (x > 50) {
      x = -2;
   }
   plane.position.x = -x;
   x += 0.02; 
});
return scene;
};s

我們將更改平面的x軸,並在其超過50時重置它。

此外,球體沿y軸旋轉。這在上例中顯示。值使用sphere.rotation.y更改。

球體使用的紋理是:images/tshphere.jpg。這些影像是本地儲存在images/資料夾中,並在下面貼上以供參考。你可以下載任何你選擇的影像,並在演示連結中使用。

Basic Element Tshphere

我們需要六張立方體影像。這些影像是本地儲存在images/cubetexture/資料夾中。你可以下載任何你選擇的影像,但是當你儲存它時,請將其儲存為nameoftheimage_nx、nameoftheimage_ny、nameoftheimage_nz、nameoftheimage_px、nameoftheimage_py、nameoftheimage_pz。請注意,選擇的影像應按順序排列,以便背景看起來像天空盒顯示的那樣逼真。

用於製作天空盒的影像是:images/cubetexture/skybox

skybox_nx

Basic Element Skybox-nx

skybox_ny

Basic Element Skybox-nx

skybox_nz

Basic Element Skybox-nx

skybox_px

Basic Element Skybox-nx

skybox_py

Basic Element Skybox-nx

skybox_pz

Basic Element Skybox-nx

BabylonJS - 材質

材質就像物體的衣服。你可以新增顏色、紋理並用它包裹你的網格。你可以使用相同的材質覆蓋許多網格。網格可以是我們在上一章示例中看到的場景 - 穿過天空的平面。

在本章中,我們將學習如何為網格新增顏色、紋理和反射。

我們將為已建立的場景新增材質。我們將透過為我們建立的所有形狀新增材質來進行。

讓我們考慮一些示例,看看如何新增材質。

語法

var materialforshapes = new BABYLON.StandardMaterial("texture1", scene);

由於這是預設材質,因此上述材質不會更改任何內容。我們將使用可用的屬性使物件看起來更吸引人。

可用的屬性如下:

看看這些應用於材質的屬性如何改變網格的外觀和感覺。

基本材質屬性 - FresnelParameters

菲涅爾是BabylonJS在standardmaterial上新增的新功能。它允許更改應用於形狀的顏色。你可以透過使用簡單的菲涅爾獲得類似玻璃的反射。菲涅爾將使你在邊緣獲得更多反射,而不是在中心獲得所有反射。

菲涅爾可用的屬性如下:

StandardMaterial.diffuseFresnelParameters
StandardMaterial.opacityFresnelParameters
StandardMaterial.reflectionFresnelParameters
StandardMaterial.emissiveFresnelParameters
StandardMaterial.refractionFresnelParameters

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            var camera = new BABYLON.ArcRotateCamera("camera1", 0, 0, 10, BABYLON.Vector3.Zero(), scene);

            camera.setPosition(new BABYLON.Vector3(0, 5, -10));

            camera.attachControl(canvas);
            camera.upperBetaLimit = Math.PI / 2;
            camera.lowerRadiusLimit = 4;

            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;

            var knot = BABYLON.Mesh.CreateTorusKnot("knot", 1, 0.4, 128, 64, 2, 3, scene);	
            var yellowSphere = BABYLON.Mesh.CreateSphere("yellowSphere", 16, 1.5, scene);
            yellowSphere.setPivotMatrix(BABYLON.Matrix.Translation(3, 0, 0));
            var yellowMaterial = new BABYLON.StandardMaterial("yellowMaterial", scene);
            yellowMaterial.diffuseColor = BABYLON.Color3.Yellow();
            yellowSphere.material = yellowMaterial;    

            // Ground
            var ground = BABYLON.Mesh.CreateBox("Mirror", 1.0, scene);
            ground.scaling = new BABYLON.Vector3(100.0, 0.01, 100.0);
            ground.material = new BABYLON.StandardMaterial("ground", scene);
            ground.material.diffuseTexture = new BABYLON.Texture("images/rainbow.png", scene);
            ground.material.diffuseTexture.uScale = 10;
            ground.material.diffuseTexture.vScale = 10;
            ground.position = new BABYLON.Vector3(0, -2, 0);

            // Main material	
            var mainMaterial = new BABYLON.StandardMaterial("main", scene);
            knot.material = mainMaterial;

            var probe = new BABYLON.ReflectionProbe("main", 512, scene);
            probe.renderList.push(yellowSphere);
            probe.renderList.push(ground);
            mainMaterial.diffuseColor = new BABYLON.Color3(1, 0.5, 0.5);
            mainMaterial.refractionTexture = probe.cubeTexture;
            mainMaterial.refractionFresnel<h3>Parameters</h3> = new BABYLON.Fresnel<h3>Parameters</h3>();
            mainMaterial.refractionFresnel<h3>Parameters</h3>.bias = 0.5;
            mainMaterial.refractionFresnel<h3>Parameters</h3>.power = 16;
            mainMaterial.refractionFresnel<h3>Parameters</h3>.leftColor = BABYLON.Color3.Black();
            mainMaterial.refractionFresnel<h3>Parameters</h3>.rightColor = BABYLON.Color3.White();
            mainMaterial.indexOfRefraction = 1.05;

            // Fog
            scene.fogMode = BABYLON.Scene.FOGMODE_LINEAR;
            scene.fogColor = scene.clearColor;
            scene.fogStart = 20.0;
            scene.fogEnd = 50.0;

            // Animations
            scene.registerBeforeRender(function () {
               yellowSphere.rotation.y += 0.01;
               //  greenSphere.rotation.y += 0.01;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Basic Material Property - FresnelParameters

解釋

以下程式碼應用菲涅爾效果。左側和右側的顏色應用於網格的邊緣。

mainMaterial.refractionFresnelParameters = new BABYLON.FresnelParameters();
mainMaterial.refractionFresnelParameters.bias = 0.5;
mainMaterial.refractionFresnelParameters.power = 16;
mainMaterial.refractionFresnelParameters.leftColor = BABYLON.Color3.Black();
mainMaterial.refractionFresnelParameters.rightColor = BABYLON.Color3.White();

Bias和power屬性控制表面上的菲涅爾效果。

在此演示中,我們使用了一個名為rainbow.png的影像。這些影像是本地儲存在images/資料夾中。你可以下載任何你選擇的影像,並在演示連結中使用。

BabylonJS - 動畫

動畫使場景更具互動性,也使它更令人印象深刻,使其看起來更逼真。讓我們現在詳細瞭解動畫。我們將對形狀應用動畫,以將其從一個位置移動到另一個位置。要使用動畫,你需要使用所需的引數建立一個動畫物件。

讓我們現在看看相同的語法:

var animationBox = new BABYLON.Animation(
   "myAnimation", 
   "scaling.x", 
   30, 
   BABYLON.Animation.ANIMATIONTYPE_FLOAT, 
   BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
);

引數

考慮與BabylonJS動畫相關的以下引數:

  • 動畫的名稱。

  • 形狀的屬性 - 例如,縮放、更改位置等。語法中顯示的是縮放;在這裡,它將沿x軸縮放盒子。

  • 請求的每秒幀數:此動畫中可能的最高FPS。

  • 在這裡,你決定並輸入將修改哪種型別的數值:是浮點數(例如,平移)、向量(例如,方向)還是四元數。

  • 確切的值是:

    • BABYLON.Animation.ANIMATIONTYPE_FLOAT

    • BABYLON.Animation.ANIMATIONTYPE_VECTOR2

    • BABYLON.Animation.ANIMATIONTYPE_VECTOR3

    • BABYLON.Animation.ANIMATIONTYPE_QUATERNION

    • BABYLON.Animation.ANIMATIONTYPE_COLOR3

  • 動畫的行為 - 停止或再次啟動動畫。

  • 使用先前的值並遞增它:

    • BABYLON.Animation.ANIMATIONLOOPMODE_RELATIVE

  • 從初始值重新開始:

    • BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE

  • 保持它們的最終值

    • BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT

讓我們現在建立動畫物件:

var animationBox = new BABYLON.Animation(
   "myAnimation", 
   "scaling.x", 
   30, 
   BABYLON.Animation.ANIMATIONTYPE_FLOAT, 
   BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
);

動畫演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);
            
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;	
            
            var pl = new BABYLON.PointLight("pl", BABYLON.Vector3.Zero(), scene);
            pl.diffuse = new BABYLON.Color3(1, 1, 1);
            pl.specular = new BABYLON.Color3(1, 1, 1);
            pl.intensity = 0.8;
            
            var box = BABYLON.Mesh.CreateBox("box", '3', scene);
            box.position = new BABYLON.Vector3(-10,0,0);

            var box1 = BABYLON.Mesh.CreateBox("box1", '3', scene);
            box1.position = new BABYLON.Vector3(0,0,0);

            var animationBox = new BABYLON.Animation("myAnimation", "scaling.x", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);

            var animationBox1 = new BABYLON.Animation("myAnimation1", "scaling.z", 10, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);

            // An array with all animation keys
            var keys = []; 

            //At the animation key 0, the value of scaling is "1"
            keys.push({
               frame: 0,
               value: 1
            });

            //At the animation key 20, the value of scaling is "0.2"
            keys.push({
               frame: 20,
               value: 0.2
            });

            keys.push({
               frame: 60,
               value: 0.4
            });

            //At the animation key 100, the value of scaling is "1"
            keys.push({
               frame: 100,
               value: 1
            });
            
            animationBox.setKeys(keys);
            box.animations = [];
            box.animations.push(animationBox);			
            scene.beginAnimation(box, 0, 100, true); 

            // An array with all animation keys
            var keys = []; 

            //At the animation key 0, the value of scaling is "1"
            keys.push({
               frame: 0,
               value: 1
            });

            //At the animation key 20, the value of scaling is "0.2"
            keys.push({
               frame: 60,
               value: 0.2
            });

            //At the animation key 100, the value of scaling is "1"
            keys.push({
               frame: 100,
               value: 1
            });
            animationBox1.setKeys(keys);
            box1.animations = [];
            box1.animations.push(animationBox1);			
            scene.beginAnimation(box1, 0, 100, true); 
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Animation Demo

// An array with all animation keys
var keys = []; 

//At the animation key 0, the value of scaling is "1"
keys.push({
   frame: 0,
   value: 1
});

//At the animation key 20, the value of scaling is "0.2"
keys.push({
   frame: 20,
   value: 0.2
});

//At the animation key 100, the value of scaling is "1"
keys.push({
   frame: 100,
   value: 1
});

animationBox.setKeys(keys);

box.animations = [];

box.animations.push(animationBox);

scene.beginAnimation(box, 0, 100, true); //defines the start and the end on the target shape box.

以下是動畫物件上可用的其他函式:

  • pause()
  • restart()
  • stop()
  • reset()

我們可以將beginAnimation引用儲存在一個變數中,並使用該引用來停止、暫停或重置動畫。

var newAnimation = scene.beginAnimation(box1, 0, 100, true);

例如:

newAnimation.pause();

動畫物件上有一些函式可用於控制關鍵幀。

BABYLON.Animation.prototype.floatInterpolateFunction = function (startValue, endValue, gradient) {
   return startValue + (endValue - startValue) * gradient;
};

BABYLON.Animation.prototype.quaternionInterpolateFunction = function (startValue, endValue, gradient) {
   return BABYLON.Quaternion.Slerp(startValue, endValue, gradient);
};

BABYLON.Animation.prototype.vector3InterpolateFunction = function (startValue, endValue, gradient) {
   return BABYLON.Vector3.Lerp(startValue, endValue, gradient);
};

以下是可以更改的函式列表:

  • floatInterpolateFunction
  • quaternionInterpolateFunction
  • quaternionInterpolateFunctionWithTangents
  • vector3InterpolateFunction
  • vector3InterpolateFunctionWithTangents
  • vector2InterpolateFunction
  • vector2InterpolateFunctionWithTangents
  • sizeInterpolateFunction
  • color3InterpolateFunction
  • matrixInterpolateFunction

要建立快速動畫,可以使用一個可以直接使用的函式。

例如:

Animation.CreateAndStartAnimation = function(name, mesh, tartgetProperty, framePerSecond, totalFrame, from, to, loopMode);

在這裡,你只能使用2個關鍵幀 - 開始結束

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);
            
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;	
            
            var pl = new BABYLON.PointLight("pl", BABYLON.Vector3.Zero(), scene);
            pl.diffuse = new BABYLON.Color3(1, 1, 1);
            pl.specular = new BABYLON.Color3(1, 1, 1);
            pl.intensity = 0.8;
            
            var box = BABYLON.Mesh.CreateBox("box", '3', scene);
            box.position = new BABYLON.Vector3(0,0,0);
            BABYLON.Animation.CreateAndStartAnimation('boxscale', box, 'scaling.x', 30, 120, 1.0, 1.5);  
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Animation Demo Image

動畫混合

你可以藉助enableBlending = true;實現動畫混合;

此混合動畫將從當前物件狀態更改。

緩動函式

為了使動畫更令人印象深刻,我們之前已經在CSS中使用了一些緩動函式。

以下是緩動函式列表:

  • BABYLON.CircleEase ()

  • BABYLON.BackEase (amplitude)

  • BABYLON.BounceEase (bounces, bounciness)

  • BABYLON.CubicEase ()

  • BABYLON.ElasticEase (oscillations, springiness)

  • BABYLON.ExponentialEase (exponent)

  • BABYLON.PowerEase (power)

  • BABYLON.QuadraticEase ()

  • BABYLON.QuarticEase ()

  • BABYLON.QuinticEase ()

  • BABYLON.SineEase ()

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);
            
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;	
            
            var pl = new BABYLON.PointLight("pl", BABYLON.Vector3.Zero(), scene);
            pl.diffuse = new BABYLON.Color3(1, 1, 1);
            pl.specular = new BABYLON.Color3(1, 1, 1);
            pl.intensity = 0.8;

            var box1 = BABYLON.Mesh.CreateTorus("torus", 5, 1, 10, scene, false);
            box1.position = new BABYLON.Vector3(0,0,0);

            var animationBox1 = new BABYLON.Animation("myAnimation1", "scaling.z", 10, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);

            // An array with all animation keys
            var keys = []; 

            //At the animation key 0, the value of scaling is "1"
            keys.push({
               frame: 0,
               value: 1
            });

            //At the animation key 20, the value of scaling is "0.2"
            keys.push({
               frame: 60,
               value: 0.2
            });

            //At the animation key 100, the value of scaling is "1"
            keys.push({
               frame: 100,
               value: 1
            });
            
            animationBox1.setKeys(keys);
            box1.animations = [];
            // box1.animations.push(animationBox1);		

            var easingFunction = new BABYLON.QuarticEase();
            easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);

            animationBox1.setEasingFunction(easingFunction);
            box1.animations.push(animationBox1);
            scene.beginAnimation(box1, 0, 100, true); 
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Animation Blending

動畫事件

您可以在動畫事件中執行任何必要的操作。如果您想在幀更改或動畫完成時更改任何內容,可以透過向動畫新增事件來實現。

var event1 = new BABYLON.AnimationEvent(50, function() { console.log("Yeah!"); }, true);
// You will get hte console.log when the frame is changed to 50 using animation.

animation.addEvent(event1); //attaching event to the animation.

BabylonJS - 精靈

在計算機圖形學中,“精靈”指的是什麼?它基本上是一個整合到更大場景中的二維點陣圖。當多個較小的影像組合成單個位圖以節省記憶體時,生成的影像稱為精靈圖。讓我們開始學習精靈及其使用方法。

使用精靈的第一步是建立一個精靈管理器。

var spriteManagerTrees = new BABYLON.SpriteManager("treesManagr", "Assets/Palm-arecaceae.png", 2000, 800, scene);

建立精靈管理器時,請考慮以下引數:

  • 名稱 - 此管理器的名稱。

  • URL - 要使用的影像URL。

  • 管理器容量 - 此管理器中的最大例項數。例如,上述例項將建立 2000 棵樹。

  • 單元格大小 - 影像所佔的大小。

  • 場景 - 將新增管理器的場景。

var spriteManagerPlayer = new BABYLON.SpriteManager("playerManagr","Assets/Player.png", 2, 64, scene);

看看上面的物件。我們提供了一個玩家影像,現在正在建立它的 2 個例項。影像大小為 64 畫素。精靈的每個影像都必須包含在 64 畫素的正方形中,不多不少。

現在讓我們建立與精靈管理器連結的相同例項。

var player = new BABYLON.Sprite("player", spriteManagerPlayer);

您可以像操作其他任何形狀或網格一樣操作此玩家物件。您可以分配位置、大小、角度等。

player.size = 0.3;
player.angle = Math.PI/4;
player.invertU = -1;
player.width = 0.3;
player.height = 0.4;

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            //scene.clearColor = new BABYLON.Color3(0, 1, 0);	
            // Create camera and light
            var light = new BABYLON.PointLight("Point", new BABYLON.Vector3(5, 10, 5), scene);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 8, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var spriteManagerTrees = new BABYLON.SpriteManager("trees", "images/tree.png", 1000, 400, scene);	

            for (var i = 0; i < 1000; i++) {
               var tree = new BABYLON.Sprite("tree", spriteManagerTrees);
               tree.position.x = Math.random() * 100 - 50;
               tree.position.z = Math.random() * 100 - 50;
               tree.isPickable = true;

               //Some "dead" trees
               if (Math.round(Math.random() * 5) === 0) {
                  tree.angle = Math.PI * 90 / 180;
                  tree.position.y = -0.3;
               }
            }

            var spriteManagerTrees1 = new BABYLON.SpriteManager("trees1", "images/tree1.png", 1000,400, scene);	

            for (var i = 0; i < 1000; i++) {
               var tree1 = new BABYLON.Sprite("tree1", spriteManagerTrees1);       
               if (i %2 == 0) {
               tree1.position.x = Math.random() * 100 - 50;			
               } else {
                  tree1.position.z = Math.random() * 100 - 50;
               }
               tree1.isPickable = true;
            }

            spriteManagerTrees.isPickable = true;
            spriteManagerTrees1.isPickable = true;

            var spriteManagerPlayer = new BABYLON.SpriteManager("playerManager", "images/bird.png", 2, 200, scene);
            
            var player = new BABYLON.Sprite("player", spriteManagerPlayer);
            player.position.x = 2;
            player.position.y = 2;	
            player.position.z = 0;	


            var spriteManagerPlayer1 = new BABYLON.SpriteManager("playerManager1", "images/bird.png", 2, 200, scene);
            
            var player1 = new BABYLON.Sprite("player", spriteManagerPlayer1);
            player1.position.x = 1;
            player1.position.y = 2;	
            player1.position.z = 0;	

            var spriteManagerPlayer2 = new BABYLON.SpriteManager("playerManager2", "images/bird.png", 2, 200, scene);
            
            var player2 = new BABYLON.Sprite("player", spriteManagerPlayer2);
            player2.position.x = 0;
            player2.position.y = 1;	
            player2.position.z = 0;	

            scene.onPointerDown = function (evt) {
               var pickResult = scene.pickSprite(this.pointerX, this.pointerY);
               if (pickResult.hit) {
                  pickResult.pickedSprite.angle += 1;
               }
            };
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

BabylonJS Sprites

在這個演示中,我們使用了名為 tree.png、tree1.png 的影像來顯示樹木,使用 bird.png 來顯示場景中的鳥。這些影像儲存在本地 images/ 資料夾中,並在下面貼上以供參考。您可以下載任何您選擇的影像並在演示連結中使用。

下面顯示了用於樹的影像。

images/tree.png

BabylonJS Sprites

images/tree1.png

BabylonJS Sprites

images/bird.png

BabylonJS Sprites

現在讓我們再看看一個帶有精靈的氣球演示。

帶有精靈的氣球演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height:100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            var light = new BABYLON.PointLight("Point", new BABYLON.Vector3(5, 10, 5), scene);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", -3.4, 1.0, 82, new BABYLON.Vector3(0, -15, 0), scene);
            camera.setPosition(new BABYLON.Vector3(30, 0,100));
            camera.attachControl(canvas, true);
            
            var spriteManagerTrees = new BABYLON.SpriteManager("trees", "images/balloon.png", 50, 450, scene);	

            var treearray = [];
            for (var i = 0; i < 50; i++) {
               var tree = new BABYLON.Sprite("tree", spriteManagerTrees);
               tree.position.x = Math.random() * 100 - 10;
               tree.position.z = Math.random() * 100 - 10;
               tree.position.y = -35;
               tree.isPickable = true;       
               treearray.push(tree);
            }

            spriteManagerTrees.isPickable = true;
            scene.onPointerDown = function (evt) {
               var pickResult = scene.pickSprite(this.pointerX, this.pointerY);
               if (pickResult.hit) {
                  pickResult.pickedSprite.position.y = -3000;			
               }
            };
            
            k = -35;
            var animate = function() {
               if (k > 3) return;
               k += 0.05;
               for (var i = 0; i < treearray.length; i++) {
                  treearray[i].position.y = k;
               }
            };
            scene.registerBeforeRender(animate);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Sprites Balloons

在這個演示中,我們使用了名為 ballon.png 的影像。這些影像儲存在本地 images/ 資料夾中,並在下面貼上以供參考。您可以下載任何您選擇的影像並在演示連結中使用。

images/balloon.png

Balloon

氣球將升上天空,一旦它們停止,您可以單擊它們,它們就會消失。這是使用 pickSprite 函式完成的,該函式在單擊建立的精靈時提供詳細資訊。

當滑鼠操作發生時,將呼叫 onPointerDown 函式,並更改精靈的位置。

var animate = function() {
   if (k > 3) return;
   k += 0.05;
   for (var i = 0; i < treearray.length; i++) {
      treearray[i].position.y = k;
   }
};
scene.registerBeforeRender(animate);

animate 函式在 registerBeforeRender 中呼叫,它負責將氣球從初始 -35 移動到 +3。透過將其遞增 0.05 來緩慢移動它。

BabylonJS - 粒子

粒子系統是計算機圖形學中的一種技術,它使用大量非常小的精靈、3D 模型或其他圖形物件來模擬某些型別的“模糊”現象,否則很難用傳統的渲染技術再現。

要建立粒子系統,您必須按如下方式呼叫該類:

var particleSystem = new BABYLON.ParticleSystem("particles", 2000, scene);//2000 refers to the total number of particles to be produced.

粒子系統需要考慮以下屬性:

particleSystem.particleTexture = new BABYLON.Texture("Flare.png", scene);
particleSystem.textureMask = new BABYLON.Color4(0.1, 0.8, 0.8, 1.0);
particleSystem.emitter = fountain
particleSystem.color1 = new BABYLON.Color4(0.7, 0.8, 1.0, 1.0);
particleSystem.color2 = new BABYLON.Color4(0.2, 0.5, 1.0, 1.0);
particleSystem.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.0);

發射器屬性採用必須從中發射粒子的網格。color1color2 是粒子的顏色。

ColorDead 是在粒子從場景中消失之前應用於粒子的顏色,因此稱為 colorDead。

particleSystem.minSize = 0.1;
particleSystem.maxSize = 0.5;
particleSystem.minLifeTime = 0.3;
particleSystem.maxLifeTime = 1.5;

MinSize 和 maxSize 是賦予粒子的尺寸。MinlifeTime 和 maxLifeTime 是賦予粒子的生命週期。

particleSystem.emitRate = 1500;

emitRate 是發射粒子的速率。

我們在下面顯示的演示中使用了圓環體。我們使用了粒子系統及其屬性來獲取圓環體周圍的所有粒子。

演示 1

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            // Setup environment
            
            var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 2, 8), scene);
            
            var camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 0.8, 20, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var fountain = BABYLON.Mesh.CreateTorus("torus", 2, 1, 8, scene, false);
            
            var particleSystem = new BABYLON.ParticleSystem("particles", 2000, scene);
            particleSystem.particleTexture = new BABYLON.Texture("images/dot.jpg", scene);

            particleSystem.textureMask = new BABYLON.Color4(0.1, 0.8, 0.8, 1.0);
            particleSystem.emitter = fountain;


            particleSystem.minEmitBox = new BABYLON.Vector3(-1, 0, 0); // Starting all from
            particleSystem.maxEmitBox = new BABYLON.Vector3(1, 0, 0); // To...

            particleSystem.color1 = new BABYLON.Color4(0.7, 0.8, 1.0, 1.0);
            particleSystem.color2 = new BABYLON.Color4(0.2, 0.5, 1.0, 1.0);
            particleSystem.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.0);

            particleSystem.minSize = 0.1;
            particleSystem.maxSize = 0.5;

            particleSystem.minLifeTime = 0.3;
            particleSystem.maxLifeTime = 1.5;

            particleSystem.emitRate = 1500;

            particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;

            particleSystem.gravity = new BABYLON.Vector3(0, -9.81, 0);

            particleSystem.direction1 = new BABYLON.Vector3(-7, 8, 3);
            particleSystem.direction2 = new BABYLON.Vector3(7, 8, -3);


            particleSystem.minAngularSpeed = 0;
            particleSystem.maxAngularSpeed = Math.PI;

            particleSystem.minEmitPower = 1;
            particleSystem.maxEmitPower = 3;
            particleSystem.updateSpeed = 0.005;

            particleSystem.start();
            var keys = [];
            var animation = new BABYLON.Animation("animation", "rotation.x", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
                                   BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
            
            // At the animation key 0, the value of scaling is "1"
            keys.push({
               frame: 0,
               value: 0
            });

            // At the animation key 50, the value of scaling is "0.2"
            keys.push({
               frame: 50,
               value: Math.PI
            });

            // At the animation key 100, the value of scaling is "1"
            keys.push({
               frame: 100,
               value: 0
            });

            // Launch animation
            animation.setKeys(keys);
            fountain.animations.push(animation);
            scene.beginAnimation(fountain, 0, 100, true);
            return scene;
         }
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });	
      </script>
   </body>
</html>	

輸出

以上程式碼行生成以下輸出:

BabylonJS Particles

在這個演示中,我們使用了名為 dot.jpg 的影像。這些影像儲存在本地 images/ 資料夾中,並在下面貼上以供參考。您可以下載任何您選擇的影像並在演示連結中使用。

以下是用於粒子紋理的影像:images/dot.jpg

Dot

演示 2

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Ball/Ground Demo</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3( .5, .5, .5);
            
            var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, new BABYLON.Vector3(0, 0, -0), scene);
            camera.setPosition(new BABYLON.Vector3(-100, 0,-100));
            camera.attachControl(canvas, true);
            
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 0.5, 0), scene);
            var pl = new BABYLON.PointLight("pl", new BABYLON.Vector3(0, 0, 0), scene);

            var gmat = new BABYLON.StandardMaterial("mat1", scene);
            gmat.alpha = 1.0;
            
            var ground =  BABYLON.Mesh.CreateGround("ground", 100, 100, 20, scene);
            ground.material = gmat;
            gmat.wireframe = true;

            var particleSystem = new BABYLON.ParticleSystem("particles", 2000, scene);
            particleSystem.particleTexture = new BABYLON.Texture("images/dot.jpg", scene);

            particleSystem.textureMask = new BABYLON.Color4(0.1, 0.8, 0.8, 1.0);
            particleSystem.emitter = ground;

            particleSystem.minEmitBox = new BABYLON.Vector3(-1, 0, 0); // Starting all from
            particleSystem.maxEmitBox = new BABYLON.Vector3(1, 0, 0); // To...

            particleSystem.color1 = new BABYLON.Color4(0.7, 0.8, 1.0, 1.0);
            particleSystem.color2 = new BABYLON.Color4(0.2, 0.5, 1.0, 1.0);
            particleSystem.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.0);

            particleSystem.minSize = 0.1;
            particleSystem.maxSize = 0.5;

            particleSystem.minLifeTime = 0.3;
            particleSystem.maxLifeTime = 1.5;

            particleSystem.emitRate = 1500;

            particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;

            particleSystem.gravity = new BABYLON.Vector3(0, -9.81, 0);

            particleSystem.direction1 = new BABYLON.Vector3(-7, 8, 3);
            particleSystem.direction2 = new BABYLON.Vector3(7, 8, -3);

            particleSystem.minAngularSpeed = 0;
            particleSystem.maxAngularSpeed = Math.PI;

            particleSystem.minEmitPower = 1;
            particleSystem.maxEmitPower = 3;
            particleSystem.updateSpeed = 0.005;

            particleSystem.start();


            var keys = [];
            var animation = new BABYLON.Animation("animation", "rotation.x", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
                           BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);

            // At the animation key 0, the value of scaling is "1"
            keys.push({
               frame: 0,
               value: 0
            });

            // At the animation key 50, the value of scaling is "0.2"
            keys.push({
               frame: 50,
               value: Math.PI
            });

            // At the animation key 100, the value of scaling is "1"
            keys.push({
               frame: 100,
               value: 0
            });

            // Launch animation
            animation.setKeys(keys);
            ground.animations.push(animation);
            
            //scene.beginAnimation(ground, 0, 100, true);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Demo Particles

帶動畫的演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Ball/Ground Demo</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3( .5, .5, .5);
            
            var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, new BABYLON.Vector3(0, 0, -0), scene);
            camera.setPosition(new BABYLON.Vector3(-100, 0, -100));
            camera.attachControl(canvas, true);
            
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 0.5, 0), scene);
            var pl = new BABYLON.PointLight("pl", new BABYLON.Vector3(0, 0, 0), scene);

            var gmat = new BABYLON.StandardMaterial("mat1", scene);
            gmat.alpha = 1.0;
            
            var ground =  BABYLON.Mesh.CreateGround("ground", 100, 100, 20, scene);
            ground.material = gmat;
            gmat.wireframe = true;

            var particleSystem = new BABYLON.ParticleSystem("particles", 2000, scene);
            particleSystem.particleTexture = new BABYLON.Texture("images/dot.jpg", scene);

            particleSystem.textureMask = new BABYLON.Color4(0.1, 0.8, 0.8, 1.0);
            particleSystem.emitter = ground;

            particleSystem.minEmitBox = new BABYLON.Vector3(-1, 0, 0); // Starting all from
            particleSystem.maxEmitBox = new BABYLON.Vector3(1, 0, 0); // To...

            particleSystem.color1 = new BABYLON.Color4(0.7, 0.8, 1.0, 1.0);
            particleSystem.color2 = new BABYLON.Color4(0.2, 0.5, 1.0, 1.0);
            particleSystem.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.0);

            particleSystem.minSize = 0.1;
            particleSystem.maxSize = 0.5;

            particleSystem.minLifeTime = 0.3;
            particleSystem.maxLifeTime = 1.5;

            particleSystem.emitRate = 1500;

            particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;

            particleSystem.gravity = new BABYLON.Vector3(0, -9.81, 0);//gravity for the particle.

            particleSystem.direction1 = new BABYLON.Vector3(-7, 8, 3);
            particleSystem.direction2 = new BABYLON.Vector3(7, 8, -3);
            
            //random direction for the particles on the scene
            particleSystem.minAngularSpeed = 0;
            particleSystem.maxAngularSpeed = Math.PI;
            particleSystem.minEmitPower = 1;
            particleSystem.maxEmitPower = 3;
            particleSystem.updateSpeed = 0.005;

            particleSystem.start();

            var keys = [];
            var animation = new BABYLON.Animation("animation", "rotation.x", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT,
                           BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
            
            // At the animation key 0, the value of scaling is "1"
            keys.push({
               frame: 0,
               value: 0
            });

            // At the animation key 50, the value of scaling is "0.2"
            keys.push({
               frame: 50,
               value: Math.PI
            });

            // At the animation key 100, the value of scaling is "1"
            keys.push({
               frame: 100,
               value: 0
            });

            // Launch animation
            animation.setKeys(keys);
            ground.animations.push(animation);
            scene.beginAnimation(ground, 0, 100, true); 
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Particles Animation

解釋

上述演示顯示了一個帶有線框材質的地面,粒子系統是從中心產生的。

BabylonJS - 相機

BabylonJS 有許多可用的相機。一次只有一個相機對場景處於活動狀態。

在本章中,我們將學習如何在 BabylonJS 中使用相機。

自由相機

現在讓我們看看自由相機是如何工作的。

語法

以下是自由相機的語法:

var camera = new BABYLON.FreeCamera("FreeCamera", new BABYLON.Vector3(0, 1, -15), scene);

這是放置相機的位置 - new BABYLON.Vector3(0, 1, -15)。

更改方向將更改方向。您可以更改值並檢視相機在場景中的行為。

以下是自由相機使用的引數:

  • 名稱
  • 位置
  • 場景

弧形旋轉相機

此相機圍繞給定的目標樞軸旋轉。可以使用游標和滑鼠或觸控事件控制它。引數是名稱、alpha、beta、半徑和目標。

語法

var camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);

ArcRotateCamera 指向 +x 方向。要更改相機的位置,請使用 setPosition 屬性。

camera.setPosition(new BABYLON.Vector3(0, 0, -100));

ArcRotateCamera 是一個非常適合製作動畫的相機。以下命令將幫助您圍繞目標旋轉相機:

scene.activeCamera.alpha += .01;

觸控相機

觸控是一種“手勢”。它可以是在觸控板或螢幕上,用手指、觸筆、手套、腳或雷射筆進行操作。任何可以感知到的運動……都可以被認為是一種手勢。

語法

以下是觸控相機的語法:

var camera = new BABYLON.TouchCamera("TouchCamera", new BABYLON.Vector3(0, 1, -15), scene);

遊戲手柄相機

此相機專為與遊戲手柄一起使用而設計。

語法

以下是遊戲手柄相機的語法:

var camera = new BABYLON.GamepadCamera("Camera", new BABYLON.Vector3(0, 15, -45), scene);

裝置方向相機

此相機專為響應裝置方向事件而設計,例如當您前後、左右傾斜裝置時。

語法

var camera = new BABYLON.DeviceOrientationCamera("DevOr_camera", new BABYLON.Vector3(0, 1, -15), scene);

跟隨相機

跟隨相機旨在跟隨任何具有位置的場景專案。它可以從後方、前方或任何角度跟隨。

語法

以下是跟隨相機的語法:

var camera = new BABYLON.FollowCamera("FollowCam", new BABYLON.Vector3(0, 15, -45), scene);

虛擬搖桿相機

此相機設計為響應虛擬搖桿事件。虛擬搖桿是用於控制相機或其他場景專案的螢幕上二維圖形。

語法

以下是虛擬搖桿相機的語法:

var camera = new BABYLON.VirtualJoysticksCamera("VJ_camera", new BABYLON.Vector3(0, 1, -15), scene);

立體眼鏡相機

立體眼鏡相機適用於紅色和青色 3D 眼鏡。它使用後處理濾鏡技術。

立體眼鏡弧形旋轉相機

以下是立體眼鏡弧形旋轉相機的語法:

var camera = new BABYLON.AnaglyphArcRotateCamera("aar_cam", -Math.PI/2, Math.PI/4, 20, new BABYLON.Vector3.Zero(), 0.033, scene);

立體眼鏡自由相機

以下是立體眼鏡自由相機的語法:

var camera = new BABYLON.AnaglyphFreeCamera("af_cam", new BABYLON.Vector3(0, 1, -15), 0.033, scene);

VR 裝置方向自由相機

VR 裝置方向自由相機使用自由相機作為其基礎,因此自由相機的屬性和方法也存在於我們的 VR 裝置方向自由相機中。

語法

以下是VR 裝置方向自由相機的語法:

var camera = new BABYLON.VRDeviceOrientationFreeCamera ("Camera", new BABYLON.Vector3 (-6.7, 1.2, -1.3), scene, 0);

WebVR 自由相機

WebVR 自由相機使用自由相機作為其基礎,因此自由相機的屬性和方法也存在於我們的 WebVR 自由相機中。

語法

以下是WebVR 自由相機的語法:

var camera = new BABYLON.WebVRFreeCamera("WVR", new BABYLON.Vector3(0, 1, -15), scene);

在大多數演示中,您將看到attachControl,其中相機連線到畫布。

示例

camera.attachControl(canvas, true);

BabylonJS - 光照

在本章中,我們將學習 BabylonJS 中使用的燈光。我們將首先看看 babylonjs 提供的不同型別的燈光。

燈光旨在產生每個畫素接收到的漫反射色和鏡面反射色。稍後,它將用於材質以獲得每個畫素的最終顏色。

babylonjs 提供 4 種類型的燈光。

  • 點光源
  • 方向光
  • 聚光燈
  • 半球光

BabylonJS - 點光源

點光源的經典示例是太陽,它的光線向各個方向傳播。點光源在空間中有一個獨特的點,從中向各個方向傳播光線。可以使用鏡面反射和漫反射屬性來控制光線顏色。

語法

以下是點光源的語法:

var light0 = new BABYLON.PointLight("Omni0", new BABYLON.Vector3(1, 10, 1), scene);

點光源有三個不同的引數:

  • 第一個引數是燈光的名稱。

  • 第二個引數是放置點光源的位置。

  • 第三個引數是需要將燈光附加到的場景。

以下屬性用於在上面建立的物件上新增顏色:

light0.diffuse = new BABYLON.Color3(1, 0, 0);
light0.specular = new BABYLON.Color3(1, 1, 1);

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3( .5, .5, .5);
            
            var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, new BABYLON.Vector3(0, 0, -0), scene);
            camera.setPosition(new BABYLON.Vector3(0, 0, -100));
            camera.attachControl(canvas, true);
            
            var pl = new BABYLON.PointLight("pl", new BABYLON.Vector3(1, 20, 1), scene);
            pl.diffuse = new BABYLON.Color3(0, 1, 0);
            pl.specular = new BABYLON.Color3(1, 0, 0);
            
            var ground = BABYLON.Mesh.CreateGround("ground", 150, 6, 2, scene);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Pointlight

BabylonJS - 方向光

在方向光中,光線由方向定義,並根據您放置它的位置向各個方向發射。

var light0 = new BABYLON.DirectionalLight("Dir0", new BABYLON.Vector3(0, -1, 0), scene);

點光源有三個不同的引數:

  • 第一個引數是燈光的名稱。

  • 第二個引數是位置。現在,它在 Y 軸上放置為負 -1。

  • 第三個引數是將要附加的場景。

在這裡,您可以使用鏡面反射和漫反射屬性新增顏色。

light0.diffuse = new BABYLON.Color3(0, 1, 0);
light0.specular = new BABYLON.Color3(1,0, 0);

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3( .5, .5, .5);
            
            var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, new BABYLON.Vector3(0, 0, -0), scene);
            camera.setPosition(new BABYLON.Vector3(0, 0, -100));
            camera.attachControl(canvas, true);
            
            var pl = new BABYLON.DirectionalLight("Dir0", new BABYLON.Vector3(0, -10, 0), scene);
            pl.diffuse = new BABYLON.Color3(0, 1, 0);
            pl.specular = new BABYLON.Color3(1, 0, 0);
            
            var ground = BABYLON.Mesh.CreateGround("ground", 150, 6, 2, scene);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Directional Light

BabylonJS - 聚光燈

聚光燈就像光線以錐形照射一樣。

語法

以下是聚光燈的語法:

var light0 = new BABYLON.SpotLight("Spot0", new BABYLON.Vector3(0, 30, -10), new BABYLON.Vector3(0, -1, 0), 0.8, 2, scene);

點光源有五個不同的引數:

  • 第一個引數是燈光的名稱。
  • 第二個引數是位置。
  • 第三個引數是方向。
  • 第四個引數是角度。
  • 第五個引數是指數。

這些值定義了一個從位置開始,朝向方向發射的光錐。鏡面反射和漫反射用於控制光線的顏色。

light0.diffuse = new BABYLON.Color3(1, 0, 0);
light0.specular = new BABYLON.Color3(1, 1, 1);

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3( .5, .5, .5);
            
            var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, new BABYLON.Vector3(0, 0, -0), scene);
            camera.setPosition(new BABYLON.Vector3(0, 0, -100));
            camera.attachControl(canvas, true);
            
            var light0 = new BABYLON.SpotLight("Spot0", new BABYLON.Vector3(0, 30, -10), new BABYLON.Vector3(0, -1, 0), 0.8, 2, scene);
            light0.diffuse = new BABYLON.Color3(0, 1, 0);
            light0.specular = new BABYLON.Color3(1, 0, 0);
            
            var ground = BABYLON.Mesh.CreateGround("ground", 80,80, 2, scene);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Spot Light

BabylonJS - 半球光

半球光更像是獲取環境光。光線的方向朝向天空。燈光賦予 3 種顏色;一種用於天空,一種用於地面,最後一種用於鏡面反射。

語法

以下是半球光的語法:

var light0 = new BABYLON.HemisphericLight("Hemi0", new BABYLON.Vector3(0, 1, 0), scene);

對於顏色

light0.diffuse = new BABYLON.Color3(1, 0, 0);
light0.specular = new BABYLON.Color3(0, 1, 0);
light0.groundColor = new BABYLON.Color3(0, 0, 0);

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3( .5, .5, .5);
            
            var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, new BABYLON.Vector3(0, 0, -0), scene);
            camera.setPosition(new BABYLON.Vector3(0, 0, -100));
            camera.attachControl(canvas, true);
            
            var light0 = new BABYLON.HemisphericLight("Hemi0", new BABYLON.Vector3(0, 1, 0), scene);
            light0.diffuse = new BABYLON.Color3(1, 0, 0);
            light0.specular = new BABYLON.Color3(0, 1, 0);
            light0.groundColor = new BABYLON.Color3(0, 0, 0);
            
            var ground = BABYLON.Mesh.CreateGround("ground", 100,100, 2, scene);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Hemispheric Light

BabylonJS - 引數化形狀

引數化形狀是指可以使用帶有彎曲、扭曲等的線條實現的不同形狀。它是由數學方程(如拋物線、正弦曲線、餘弦曲線、貝塞爾曲線等)生成的二維形式。使用該方程,我們可以找到座標 (x, y) 並繪製相同的線條。在本章中,我們將看到諸如飄帶、線條、虛線、管狀、擠壓之類的形狀。可以使用下面描述的引數化形狀在板上實現手繪線條。

序號。 引數化形狀和描述
1 飄帶

Ribbon 接收一系列路徑作為輸入,並沿著這些路徑繪製線條。它使用複雜的邏輯來獲取座標。在下面給出的示例中,我們使用了貝塞爾曲線方程來繪製 Ribbon。貝塞爾曲線主要用於 3D 遊戲中模擬平滑曲線。曲線需要控制點,曲線沿著控制點繪製。

2 線條

線條是 3D 遊戲中的基本元素。要繪製一條線,您需要兩點,您可以在這兩點之間繪製一條線。

3

管狀體是一種彎曲的圓柱體形狀。它可以根據應用於它的方程(數學函式)來獲得座標,從而產生不同的引數化形狀。

4 擠壓

擠壓有助於將二維形狀轉換為體積形狀。假設您想建立一個二維星形,您將擁有 x、y 座標,而 z 將為 0。透過二維座標,擠壓會將其轉換為三維形狀。因此,二維星形透過擠壓將變成三維的。您可以嘗試不同的二維形狀並將它們轉換為三維形狀。

BabylonJS - 網格

在本章中,我們將學習如何使用網格構建器建立不同的形狀。我們已經在之前的章節中學習瞭如何建立形狀。

不同之處在於,使用網格構建器可以讓您靈活地為形狀新增顏色和影像。

使用 MeshBuilder 建立立方體

現在讓我們看看如何使用 MeshBuilder 建立立方體。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 0, 1);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;

            var pl = new BABYLON.PointLight("pl", BABYLON.Vector3.Zero(), scene);
            pl.diffuse = new BABYLON.Color3(1, 1, 1);
            pl.specular = new BABYLON.Color3(1, 1, 1);
            pl.intensity = 0.8;

            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(0, 1, 0);
            
            var texture = new BABYLON.Texture("images/cube.png", scene);
            mat.diffuseTexture = texture;

            var hSpriteNb =  3;  // 3 sprites per raw
            var vSpriteNb =  2;  // 2 sprite raws

            var faceUV = new Array(6);
            for (var i = 0; i < 6; i++) {
               faceUV[i] = new BABYLON.Vector4(i/hSpriteNb, i/vSpriteNb, (i+1)/hSpriteNb, (i+1)/vSpriteNb);
            }

            var options = {
               width: 1.5,
               height: 1.5,
               depth: 1.5,
               faceUV: faceUV
            };

            var box = BABYLON.MeshBuilder.CreateBox("box", options, scene);
            box.material = mat;

            scene.registerBeforeRender(function() { 
               pl.position = camera.position;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

MeshBuilder CubeBox

對於上面的示例,我們使用瞭如下所示的精靈影像。它水平方向有 3 列,垂直方向有 2 行。

Cube

在這個演示中,我們使用了一個名為 cube.png 的影像。這些影像儲存在本地 images/ 資料夾中,並在下面貼上以供參考。請注意,cube.png 是一個精靈影像,精靈影像是影像的集合。我們想在立方體上顯示影像,所以需要將立方體的所有側面放在一起。您也可以下載您選擇的類似精靈影像,並在演示連結中使用。

createBox 構建器為您提供了尺寸選項。

例如:

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

演示

var hSpriteNb =  3;  // 3 sprites per raw ie colums horizontally as shown in the image

var vSpriteNb =  2;  // 2 sprite raws as shown in the image above.

var faceUV = new Array(6); // the cube has 6 sides so creating array for same.
for (var i = 0; i < 6; i++) {
   faceUV[i] = new BABYLON.Vector4(i/hSpriteNb, i/vSpriteNb, (i+1)/hSpriteNb, (i+1)/vSpriteNb);
}

var options = {
   width: 1.5,
   height: 1.5,
   depth: 1.5,
   faceUV: faceUV
};

這稱為使用 createBox 方法將紋理應用於網格構建器。我們使用了影像 **cube.png**,它水平方向有 3 列,垂直方向有 2 行。立方體或盒子有 6 個面。

要應用紋理,我們使用 options 引數。例如:

Var box = BABYLON.MeshBuilder.CreateBox ('box', options, scene);

我們定義了一個名為 faceUV 的陣列,大小為 6,這是立方體的各個面。此陣列將始終包含 Vector4 元素。每個 Vector4(x, y, z, w) 將定義如下:

  • x = Ubottom
  • y = Vbottom
  • z = Utop
  • w = Vtop

這些向量在 [0, 1] 範圍內。Ubottom 和 Vbottom 是紋理裁剪開始處的左下角點的二維座標。Utop、Vtop 是紋理裁剪結束處的右上角點。

var hSpriteNb =  3;  // 3 sprites per raw
var vSpriteNb =  2;  // 2 sprite raws

var faceUV = new Array(6);
for (var i = 0; i < 6; i++) {
   faceUV[i] = new BABYLON.Vector4(i/hSpriteNb, i/vSpriteNb, (i+1)/hSpriteNb, (i+1)/vSpriteNb);
}

假設預設紋理(即給定的影像)應用於盒子的所有面。如果您只想更改盒子的一個面或一個側面,您可以直接分配如下所示的值:

var hSpriteNb =  3;  // 3 sprites per raw
var vSpriteNb =  2;  // 2 sprite raws

var faceUV = new Array(6);
faceUV[4] = new BABYLON.Vector4(0, 0, 1/hSpriteNb, 1/vSpriteNb);

示例

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 0, 1);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;

            var pl = new BABYLON.PointLight("pl", BABYLON.Vector3.Zero(), scene);
            pl.diffuse = new BABYLON.Color3(1, 1, 1);
            pl.specular = new BABYLON.Color3(1, 1, 1);
            pl.intensity = 0.8;

            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(0.8, 0.8, 0.8);
            
            var texture = new BABYLON.Texture("images/3d.png", scene);
            mat.diffuseTexture = texture;

            var hSpriteNb =  3;  // 3 sprites per raw
            var vSpriteNb =  2;  // 2 sprite raws

            var faceUV = new Array(6);
            faceUV[4] = new BABYLON.Vector4(0, 0, 1/hSpriteNb, 1/vSpriteNb);

            var options = {
               width:3,
               height:3,
               depth: 3,
               faceUV:faceUV
            };

            var box = BABYLON.MeshBuilder.CreateBox("box", options, scene);
            box.material = mat;

            scene.registerBeforeRender(function() { 
               pl.position = camera.position;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Textturepahse4

在這個演示中,我們使用了一個名為 3d.png 的影像。這些影像儲存在本地 images/ 資料夾中,並在下面貼上以供參考。請注意,3d.png 是一個精靈影像;精靈影像是影像的集合。我們想在立方體上顯示影像,將立方體的所有側面放在一起。您也可以下載您選擇的類似精靈影像,並在演示連結中使用。

用於盒子的紋理 - **images/3d.png**

3d

MeshCylinder

在本節中,我們將瞭解如何建立 MeshCylinder。

要建立 MeshCylinder,您需要使用 BABYLON.MeshBuilder.CreateCylinder 類。

該類的引數如下:

var meshcylinder = BABYLON.MeshBuilder.CreateCylinder("meshcylinder", {
   height: 3,
   diameter: 35,
   tessellation: 52
}, scene);

使用網格和網格構建器建立 Cylinder 之間的區別在於 - 您可以在網格構建器中使用 options。現在我們使用高度、直徑和細分作為傳遞給圓柱體的選項。我們使用帶有線框的標準材質作為此網格的材質。檢查瀏覽器中的輸出並檢視圓柱體。您可以在遊戲中使用類似的結構作為場景中旋轉的車輪。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>Babylon.js demo - Mesh Builder</title>
      <script src = "babylon.js"></script>
      <style>
         html,body,canvas { margin: 0; padding: 0; width: 100%; height: 100%; font-size: 0; }
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0.8, 0.8, 0.8);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 6, 1.3, 40, new BABYLON.Vector3(0, -3, 0), scene);
            
            var light = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);

            var mat = new BABYLON.StandardMaterial("mat", scene);
            mat.diffuseColor = new BABYLON.Color3(0.1, .5, 0);
            mat.specularColor = new BABYLON.Color3(0, 0, 0);
            mat.wireframe = true;

            var meshcylinder = BABYLON.MeshBuilder.CreateCylinder("meshcylinder", {
               height: 3,
               diameter: 35,
               tessellation: 52
            }, scene);

            meshcylinder.material = mat;
            meshcylinder.position = new BABYLON.Vector3(0, 0, 0);

            scene.activeCamera.attachControl(canvas);
            return scene;
         };
         
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Meshcylinder

現在,許多使用網格構建器建立的形狀將一起在一個演示中使用。下面演示連結中介紹的形狀將在後續章節中列出。

BabylonJS – 網格相交和點

遊戲中的網格相交很重要,因為您知道當遊戲中的兩個物體相交時需要做什麼。下面的演示解釋了當網格相交時需要捕獲的事件。

在下面的演示中,我們介紹了以下兩個概念:

  • 相交網格
  • 相交點
<!doctype html>
<html>
   <head>
   <meta charset = "utf-8">
   <title>BabylonJs - Basic Element-Creating Scene</title>
   <script src = "babylon.js"></script>
   <style>
      canvas {width: 100%; height: 100%;}
   </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 1, 1);
            
            var camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 0.8, 20, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var matcone = new BABYLON.StandardMaterial("mat1", scene);
            matcone.alpha = 1.0;
            matcone.diffuseColor = new BABYLON.Color3(0, 0, 0);
            matcone.wireframe = true;

            var cone = BABYLON.MeshBuilder.CreateCylinder("cone", {height : 10, diameterTop: 10,diameterBottom:10, tessellation: 5}, scene);
            cone.position= new BABYLON.Vector3(12,1,0);
            cone.material = matcone;	

            var balloon1 = BABYLON.Mesh.CreateSphere("balloon1",5, 1.0, scene);
            var balloon2 = BABYLON.Mesh.CreateSphere("balloon2", 5, 1.0, scene);
            var balloon3 = BABYLON.Mesh.CreateSphere("balloon3", 5, 1.0, scene);
            
            balloon1.material = new BABYLON.StandardMaterial("matBallon", scene);
            balloon2.material = new BABYLON.StandardMaterial("matBallon", scene);
            balloon3.material = new BABYLON.StandardMaterial("matBallon", scene);

            balloon1.position = new BABYLON.Vector3(4, 2, 0);
            balloon2.position = new BABYLON.Vector3(5, 1, 0);
            balloon3.position = new BABYLON.Vector3(7, 0, 0);

            var pointToIntersect = new BABYLON.Vector3(10, 0, 0);
            var a = 0.01;
            
            scene.registerBeforeRender(function () {
               if (balloon1.intersectsMesh(cone, false)) {
                  balloon1.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
               } 
               else {
                  balloon1.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
               }

               if (balloon2.intersectsMesh(cone, false)) {
                  balloon2.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
               } 
               else {
                  balloon2.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
               }

               if (balloon3.intersectsMesh(cone, false)) {
                  balloon3.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
               } 
               else {
                  balloon3.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
               }

               if (balloon3.intersectsPoint(pointToIntersect)) {
                  balloon3.material.emissiveColor = new BABYLON.Color3(0, 0, 0);
               }

               a += 0.01;
               balloon1.position.x += Math.cos(a) / 10;
               balloon2.position.x += Math.cos(a) / 10;
               balloon3.position.x += Math.cos(a) / 10;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼生成以下輸出:

Mesh Intersection Point

解釋

使用上面的程式碼,我們建立了一個線框為 true 的圓柱體。我們建立了 3 個球體。球體的原始顏色為綠色。

在 **scene.registerBeforeRender** 函式中,我們將根據與網格(此處為圓柱體)的相交來更改球體的顏色。

考慮 **registerBeforeRender** 中的以下程式碼:

if (balloon1.intersectsMesh(cone, false)) {
   balloon1.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
} else {
   balloon1.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
}

**intersectsMesh** 如果與傳遞給它的引數中給出的網格相交,則返回 true 或 false。

例如:

balloon1.intersectsMesh(cone, false); //cone refers to the cylinder mesh here.

如果球體與圓柱體相交,則球體的顏色將變為紅色;否則為綠色。

以下程式碼用於點相交:

var pointToIntersect = new BABYLON.Vector3(10, 0, 0);
if (balloon3.intersectsPoint(pointToIntersect)) {
   balloon3.material.emissiveColor = new BABYLON.Color3(0, 0, 0);
}

這裡,**pointtoIntersect** 變數是位置向量,在 x 軸上為 10。如果球體穿過相交點,則球體的顏色將變為黑色。

BabylonJS – 網格拾取碰撞

拾取碰撞實際上會為您提供座標,您可以將網格放置在該位置。物體由滑鼠拾取,您可以將其放置在滑鼠單擊的位置。假設您需要將網格(物體)放置在使用者單擊滑鼠的位置;因此,藉助拾取碰撞,它可以幫助您獲得單擊位置的座標。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
      canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 1, 1);

            // setup environment
            var light0 = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 10, 20), scene);
            var freeCamera = new BABYLON.FreeCamera("FreeCamera", new BABYLON.Vector3(0, 0, -30), scene);

            var balloon1 = BABYLON.Mesh.CreateSphere("balloon1",5, 1.0, scene);
            var balloon2 = BABYLON.Mesh.CreateSphere("balloon2", 5, 1.0, scene);
            balloon1.material = new BABYLON.StandardMaterial("matBallon", scene);
            balloon2.material = new BABYLON.StandardMaterial("matBallon", scene);

            balloon1.position = new BABYLON.Vector3(0, 0, -0.1);
            balloon2.position = new BABYLON.Vector3(0, 0, -0.1);
            balloon1.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
            balloon2.material.emissiveColor = new BABYLON.Color3(0, 0, 1);

            //Wall
            var wall = BABYLON.Mesh.CreatePlane("wall", 30.0, scene);
            wall.material = new BABYLON.StandardMaterial("wallMat", scene);
            wall.material.emissiveColor = new BABYLON.Color3(0.5, 1, 0.5);

            //When pointer down event is raised

            scene.onPointerDown = function (evt, pickResult) {
               // if the click hits the ground object, we change the impact position
               if (pickResult.hit) {
                  var dateValue = new Date();
                  var secondNumber = dateValue.getSeconds();
                  if (secondNumber % 2 == 0) {
                  balloon1.position.x = pickResult.pickedPoint.x;
                  balloon1.position.y = pickResult.pickedPoint.y;
                  } else {
                     balloon2.position.x = pickResult.pickedPoint.x;
                     balloon2.position.y = pickResult.pickedPoint.y;
                  }
               }
            };
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Picking collision

解釋

在上面的示例中,我們使用了一個平面和 2 個球體。要生成此輸出,請使用以下程式碼:

scene.onPointerDown = function (evt, pickResult) {
   
   // if the click hits the ground object, we change the impact position
   if (pickResult.hit) {
      var dateValue = new Date();
      var secondNumber = dateValue.getSeconds();
      if (secondNumber % 2 == 0) {
      balloon1.position.x = pickResult.pickedPoint.x;
      balloon1.position.y = pickResult.pickedPoint.y;
      } 
      else {
         balloon2.position.x = pickResult.pickedPoint.x;
         balloon2.position.y = pickResult.pickedPoint.y;
      }
   }
};

事件 **scene.onPointerDown** 為您提供座標 -x、y 和 z,在我們的示例中為 **pickResult**。

如果您單擊地面網格,它會將 pickResult.hit 設定為 true。我們考慮奇數/偶數秒,並將球體的 z 和 y 座標位置更改為 pickResult,如上所示。位置更改後,球體將放置在您單擊並定位滑鼠的位置。您可以嘗試上面的演示。

BabylonJS – 光線投射

光線投射就像太陽的光線,用於檢查場景中的碰撞和相交。

語法

var ray = new BABYLON.Ray(origin, direction, length);

引數

考慮光線投射的以下引數:

  • **起點** - 光線開始的位置。

  • **方向** - 光線的方向計算如下:

var forward = new BABYLON.Vector3(0,0,1);		
forward = vecToLocal(forward, box);
var direction = forward.subtract(origin);

然後,要獲得方向,我們從起點(盒子的位置)中減去它:

  • **長度** - 光線的長度。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 100, 100), scene);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 100, new BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, true);

            var ground = BABYLON.Mesh.CreateGround("ground", 500, 500, 10, scene);

            var box = BABYLON.Mesh.CreateBox("box", 4.0, scene);
            box.position.y = 2;
            box.scaling.z = 2;
           
            var matBox = new BABYLON.StandardMaterial("matBox", scene);
            matBox.diffuseColor = new BABYLON.Color3(0.8, 0.1, 0.5);
            box.material = matBox;
            box.isPickable = false; 

            var box2 = BABYLON.Mesh.CreateBox("box2", 8.0, scene);
            box2.position = new BABYLON.Vector3(-20, 4, 0); 
            
            var matBox2 = new BABYLON.StandardMaterial("matBox2", scene);
            matBox2.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box2.material = matBox2;

            var box3 = BABYLON.Mesh.CreateBox("box3", 8.0, scene);
            box3.position = new BABYLON.Vector3(20, 4, 0); 
            
            var matBox3 = new BABYLON.StandardMaterial("matBox3", scene);
            matBox3.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box3.material = matBox3;

            var box4 = BABYLON.Mesh.CreateBox("box4", 8.0, scene);
            box4.position = new BABYLON.Vector3(0, 0, 20); 
            
            var matBox4 = new BABYLON.StandardMaterial("matBox4", scene);
            matBox4.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box4.material = matBox4;

            var box5 = BABYLON.Mesh.CreateBox("box5", 8.0, scene);
            box5.position = new BABYLON.Vector3(0, 0, -20); 
            
            var matBox5 = new BABYLON.StandardMaterial("matBox5", scene);
            matBox5.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box5.material = matBox5;

            function mousemovef() {
               var pickResult = scene.pick(scene.pointerX, scene.pointerY);

               if (pickResult.hit) {
                  var diffX = pickResult.pickedPoint.x - box.position.x;
                  var diffY = pickResult.pickedPoint.z - box.position.z;
                  box.rotation.y = Math.atan2(diffX,diffY);			
               }	
            }

            scene.onPointerMove = function () {
               mousemovef();
            };

            function vecToLocal(vector, mesh) {
               var m = mesh.getWorldMatrix();
               var v = BABYLON.Vector3.TransformCoordinates(vector, m);
               return v;		
            }   

            scene.registerBeforeRender(function () {
               var origin = box.position;

               var forward = new BABYLON.Vector3(0,0,1);		
               forward = vecToLocal(forward, box);

               var direction = forward.subtract(origin);
               direction = BABYLON.Vector3.Normalize(direction);

               var length = 100;

               var ray = new BABYLON.Ray(origin, direction, length);
               // ray.show(scene, new BABYLON.Color3(1, 1, 0.1));

               var hit = scene.pickWithRay(ray);

               if (hit.pickedMesh) {
                  hit.pickedMesh.scaling.y  += 0.01;
               }
            });		
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Raycast

解釋

中心有一個主盒子作為光線投射。一旦它指向任何盒子,盒子的尺寸就會增加。此概念在玩遊戲時非常有用,可以知道哪些其他物體正在接觸,並可以採取必要的措施。

新增 **box.isPickable = false;**,以便不考慮中心的主盒子。如果您不想將任何物體包含在接觸的光線中,請向其新增 **box.isPickable = false;**。

以下程式碼添加了被光線拾取的盒子的縮放。

scene.registerBeforeRender(function () {
   var origin = box.position;	
   var forward = new BABYLON.Vector3(0,0,1);		
   forward = vecToLocal(forward, box);

   var direction = forward.subtract(origin);
   direction = BABYLON.Vector3.Normalize(direction);

   var length = 100;

   var ray = new BABYLON.Ray(origin, direction, length);

   var hit = scene.pickWithRay(ray);

   if (hit.pickedMesh) {
      hit.pickedMesh.scaling.y  += 0.01;
   }
});	

**var ray = new BABYLON.Ray(origin, direction, length);** 建立一條光線,它將主盒子的位置作為起點。

光線的方向計算如下:

var forward = new BABYLON.Vector3(0,0,1);		
forward = vecToLocal(forward, box);
var direction = forward.subtract(origin);

然後,要獲得方向,我們從起點(盒子的位置)中減去它。函式 **vecToLocal** 旨在透過將向量乘以網格矩陣來轉換從網格角度來看的位置。

我們使用 **var hit = scene.pickWithRay(ray);** 獲取光線中的命中點。

它給出光線與網格重合的位置。

透過執行以下程式碼行,縮放應用於被拾取的網格:

if (hit.pickedMesh) {
   hit.pickedMesh.scaling.y  += 0.01;
}

在瀏覽器中嘗試上面的示例以檢視輸出。

帶有謂詞函式的光線投射

現在讓我們看看帶有謂詞函式的光線投射是如何工作的以及用 rayhelper 顯示的方向。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(0, 100, 100), scene);
            var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 100, new BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, true);

            var ground = BABYLON.Mesh.CreateGround("ground", 500, 500, 10, scene);

            var box = BABYLON.Mesh.CreateBox("box", 4.0, scene);
            box.position.y = 2;
            box.scaling.z = 2;
            var matBox = new BABYLON.StandardMaterial("matBox", scene);
            matBox.diffuseColor = new BABYLON.Color3(0.8, 0.1, 0.5);
            box.material = matBox;
            box.isPickable = false; 

            var box2 = BABYLON.Mesh.CreateBox("box2", 8.0, scene);
            box2.position = new BABYLON.Vector3(-20, 4, 0); 
            var matBox2 = new BABYLON.StandardMaterial("matBox2", scene);
            matBox2.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box2.material = matBox2;

            var box3 = BABYLON.Mesh.CreateBox("box3", 8.0, scene);
            box3.position = new BABYLON.Vector3(20, 4, 0); 
            var matBox3 = new BABYLON.StandardMaterial("matBox3", scene);
            matBox3.diffuseColor = new BABYLON.Color3(1, 0, 0);
            box3.material = matBox3;

            var box4 = BABYLON.Mesh.CreateBox("box4", 8.0, scene);
            box4.position = new BABYLON.Vector3(0, 0, 20); 
            var matBox4 = new BABYLON.StandardMaterial("matBox4", scene);
            matBox4.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box4.material = matBox4;

            var box5 = BABYLON.Mesh.CreateBox("box5", 8.0, scene);
            box5.position = new BABYLON.Vector3(0, 0, -20); 
            var matBox5 = new BABYLON.StandardMaterial("matBox5", scene);
            matBox5.diffuseColor = new BABYLON.Color3(0, 1, 0);
            box5.material = matBox5;

            //ray showing the direction
            var ray = new BABYLON.Ray();
            var rayHelper = new BABYLON.RayHelper(ray);

            var localMeshDirection = new BABYLON.Vector3(0, 0, -1);
            var localMeshOrigin = new BABYLON.Vector3(0, 0, -.4);
            var length = 10;

            rayHelper.attachToMesh(box, localMeshDirection, localMeshOrigin, length);
            rayHelper.show(scene);

            function mousemovef() {
               var pickResult = scene.pick(scene.pointerX, scene.pointerY);

               if (pickResult.hit) {
                  var diffX = pickResult.pickedPoint.x - box.position.x;
                  var diffY = pickResult.pickedPoint.z - box.position.z;
                  box.rotation.y = Math.atan2(diffX,diffY);			
               }	
            }

            scene.onPointerMove = function () {
               mousemovef();
            };

            function vecToLocal(vector, mesh) {
               var m = mesh.getWorldMatrix();
               var v = BABYLON.Vector3.TransformCoordinates(vector, m);
               return v;		
            }   

            scene.registerBeforeRender(function () {
               var origin = box.position;
               function predicate(mesh) {
                  if (mesh == box2 || mesh == box || mesh == box5) {
                     return false;
                  }
                  return true;
               }
               
               var forward = new BABYLON.Vector3(0,0,1);		
               forward = vecToLocal(forward, box);

               var direction = forward.subtract(origin);
               direction = BABYLON.Vector3.Normalize(direction);

               var length = 100;

               var ray = new BABYLON.Ray(origin, direction, length);
               // ray.show(scene, new BABYLON.Color3(1, 1, 0.1));

               var hit = scene.pickWithRay(ray, predicate);
               if (hit.pickedMesh) {
                  hit.pickedMesh.scaling.y  += 0.01;
               }
            });		
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Raycast Predicate

解釋

帶有謂詞函式的光線投射有助於選擇我們想要的網格。如果我們不想拾取網格,我們可以忽略它。

function predicate(mesh) {
   if (mesh == box2 || mesh == box || mesh == box5) {
      return false;
   }
   return true;
}

上述函式給出被光線選擇的網格。如果選擇的網格是 box2、box 或 box5,它將返回 false;否則返回 true。

您可以嘗試上面的示例。

BabylonJS – 網格陰影

陰影根據光線照射到建立的網格的方式進行渲染。它們在使 3D 世界中的輸出看起來更逼真方面發揮著重要作用。

現在讓我們學習如何使用 babylonjs 建立陰影。

語法

var shadowGenerator00 = new BABYLON.ShadowGenerator(shadowsize, light);

引數

考慮以下與網格陰影相關的引數:

  • **陰影大小** - 陰影的大小。

  • **光線** - 場景中使用的光線。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(1, 1, 1);	
            var camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 0.8, 20, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);
            // light1
            var light = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(-1, -2, -1), scene);
            light.position = new BABYLON.Vector3(20, 40, 20);

            var ground01 = BABYLON.Mesh.CreateGround("Spotlight Hard Shadows", 24, 60, 1, scene, false);
            var groundMaterial = new BABYLON.StandardMaterial("ground", scene);
            groundMaterial.diffuseTexture = new BABYLON.Texture("images/gr1.jpg", scene);
            groundMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
            groundMaterial.emissiveColor = new BABYLON.Color3(0.2, 0.2, 0.2);

            ground01.material = groundMaterial;
            ground01.receiveShadows = true;
            ground01.position.x = -5;

            var box = BABYLON.Mesh.CreateBox("box", 3.0, scene);
            box.position.x = -5;
            box.position.y = 5;
            var shadowGenerator00 = new BABYLON.ShadowGenerator(512, light);
            shadowGenerator00.getShadowMap().renderList.push(box);
            //shadowGenerator00.usePoissonSampling = true;
            //shadowGenerator00.useExponentialShadowMap = true;
            shadowGenerator00.useBlurExponentialShadowMap = true;
            shadowGenerator00.bias = 0.01;
            scene.registerBeforeRender(function() {
               box.rotation.x += 0.01;
               box.rotation.x += 0.01;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Shadows

解釋

要建立陰影,您需要建立 shadowgenerator。考慮以下示例:

var shadowGenerator00 = new BABYLON.ShadowGenerator(512, light);

要定義需要陰影的網格,您需要將其新增到上面的生成器中。

shadowGenerator00.getShadowMap().renderList.push(box);

現在,我們建立了一個地面和一個位於其頂部的盒子。我們希望盒子的陰影落在地面上。為此,我們需要確保地面被標記為接收陰影,方法如下:

ground01.receiveShadows = true;

有一些可用於陰影的濾鏡,如下所示:

shadowGenerator.usePoissonSampling = true; - Called Poisson sampling 
shadowGenerator.useExponentialShadowMap = true; - Exponential Shadow Map
shadowGenerator.useBlurExponentialShadowMap= true;  - Blur Exponential Shadow Map

在我們的演示中,我們使用了 shadowGenerator00.useBlurExponentialShadowMap = true; 您可以嘗試其他方法,看看輸出是什麼樣的。

這裡,我們使用了名為 gr1.jpg 的影像。這些影像儲存在本地 images/ 資料夾中。您可以下載任何您選擇的影像,並在演示連結中使用。

BabylonJS – 網格上的高階紋理

在本節中,我們將學習有關網格上高階紋理的知識。不同的紋理如下所示:

讓我們將一些複雜的紋理應用於網格 - 映象、凹凸、影片和折射。

序號。 網格和描述
1 MeshHightlight 層

高亮層用於突出顯示場景中的網格。您可以為其著色,顏色將應用於網格的邊界。如果您想在遊戲中突出顯示,可以使用網格高亮層。

2 變形網格

變形透過某種轉換方式將物體的形狀更改為另一種形狀。我們已經看到了形狀的可更新引數;否則該引數設定為 false。對於變形,它設定為 true,並且網格會更新以更改形狀。

3 網格操作

操作用於向網格新增互動。當您單擊網格或網格相交或碰撞時,事件會被啟用。

4 Mesh AssetsManager

使用 assestsmanager 類,您可以在場景中載入網格、影像和二進位制檔案。

5 匯入網格

我們將學習如何使用匯入網格。

6 網格變形目標

我們已經看到了線條、條帶、多邊形等的變形。在本演示中,我們將看到球體和盒子的變形。透過變形目標,球體的形狀會發生變化,如下面的演示所示。

7 網格例項

如果要在場景中繪製相同的網格,請使用例項。

8 網格LOD與例項

LOD代表距離等級(Level Of Detail)。此功能允許您根據檢視者的距離指定網格。隨著檢視者到物件的距離增加,網格的細節級別將使用LOD清晰地顯示。

9 網格體積光散射後處理

此過程會散射光線,如下面的輸出所示。在瀏覽器中測試一下,您將看到光線如何穿過網格散射。

10 網格邊緣渲染器

邊緣渲染用於繪製網格周圍的邊緣,如上圖輸出所示。

11 網格混合模式

可以透過修改材質的alphamode來建立混合模式。

12 網格實體粒子

實體粒子系統在網格上更新。我們在網格上看到的全部屬性都可以在實體粒子中使用。

13 網格面數據

面數據佔用大量記憶體,此功能預設情況下未啟用。要啟用它,我們需要根據需要建立一個網格並向其更新面數據。

BabylonJS - 向量位置和旋轉

在您的瀏覽器中執行下面給出的演示連結。在下面的演示中,我們繪製了x、y和z軸。在正負方向上,x、y和z軸上都標有數字。在瀏覽器中執行相同的程式碼,根據需要更改值,繪製形狀、網格,定位它們,並檢視它們如何在x、y和z軸上渲染。使用x、y和z軸上提到的數字,將有助於檢視網格的位置是如何完成的。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3( .5, .5, .5);

            // camera
            var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, new BABYLON.Vector3(5, 3, 0), scene);
            camera.setPosition(new BABYLON.Vector3(5, 10, -10));
            camera.attachControl(canvas, true);
            
            // lights
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 0.5, 0), scene);
            light.intensity = 0.8;
            var spot = new BABYLON.SpotLight(
               "spot", 
               new BABYLON.Vector3(25, 15, -10), 
               new BABYLON.Vector3(-1, -0.8, 1), 15, 1, scene);
            spot.diffuse = new BABYLON.Color3(1, 1, 1);
            spot.specular = new BABYLON.Color3(0, 0, 0);
            spot.intensity = 0.2; 
            
            // material
            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(0.5, 0.5, 1.0);
            mat.backFaceCulling = false;
            //mat.wireframe = true;

            // show axis
            var showAxis = function(size) {
               var makeTextPlane = function(text, color, size) {
                  var dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", 50, scene, true);
                  dynamicTexture.hasAlpha = true;
                  dynamicTexture.drawText(text, 5, 40, "bold 36px Arial", color , "transparent", true);
                  
                  var plane = new BABYLON.Mesh.CreatePlane("TextPlane", size, scene, true);
                  plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial", scene);
                  plane.material.backFaceCulling = false;
                  
                  plane.material.specularColor = new BABYLON.Color3(0, 0, 0);
                  plane.material.diffuseTexture = dynamicTexture;
                  return plane;
               };

               var axisX = BABYLON.Mesh.CreateLines("axisX", [ 
                  new BABYLON.Vector3(-size * 0.95, 0.05 * size, 0),
                  new BABYLON.Vector3(-size, 0, 0), 
                  new BABYLON.Vector3(-size * 0.95, -0.05 * size, 0),
                  new BABYLON.Vector3(-size, 0, 0),
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(size, 0, 0), 
                  new BABYLON.Vector3(size * 0.95, 0.05 * size, 0), 
                  new BABYLON.Vector3(size, 0, 0), 
                  new BABYLON.Vector3(size * 0.95, -0.05 * size, 0)
               ], scene);
               
               axisX.color = new BABYLON.Color3(1, 0, 0);
               var xChar = makeTextPlane("X", "red", size / 10);
               xChar.position = new BABYLON.Vector3(0.9 * size, -0.05 * size, 0);

               var xChar1 = makeTextPlane("-X", "red", size / 10);
               xChar1.position = new BABYLON.Vector3(-0.9 * size, 0.05 * size, 0);

               var axisY = BABYLON.Mesh.CreateLines("axisY", [
                  new BABYLON.Vector3( -0.05 * size, -size * 0.95, 0),
                  new BABYLON.Vector3(0, -size, 0),
                  new BABYLON.Vector3(0.05 * size, -size * 0.95, 0),
                  new BABYLON.Vector3(0, -size, 0), 
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(0, size, 0), 
                  new BABYLON.Vector3( -0.05 * size, size * 0.95, 0), 
                  new BABYLON.Vector3(0, size, 0), 
                  new BABYLON.Vector3( 0.05 * size, size * 0.95, 0)
               ], scene);
               
               axisY.color = new BABYLON.Color3(0, 1, 0);
               var yChar = makeTextPlane("Y", "green", size / 10);
               yChar.position = new BABYLON.Vector3(0, 0.9 * size, -0.05 * size);
               var yChar1 = makeTextPlane("-Y", "green", size / 10);
               yChar1.position = new BABYLON.Vector3(0, -0.9 * size, 0.05 * size);

               var axisZ = BABYLON.Mesh.CreateLines("axisZ", [
                  new BABYLON.Vector3( 0 , -0.05 * size, -size * 0.95), 
                  new BABYLON.Vector3(0, 0, -size),
                  new BABYLON.Vector3( 0 , 0.05 * size, -size * 0.95),
                  new BABYLON.Vector3(0, 0, -size), 
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(0, 0, size), 
                  new BABYLON.Vector3( 0 , -0.05 * size, size * 0.95),
                  new BABYLON.Vector3(0, 0, size), 
                  new BABYLON.Vector3( 0, 0.05 * size, size * 0.95)
               ], scene);
               
               axisZ.color = new BABYLON.Color3(0, 0, 1);
               var zChar = makeTextPlane("Z", "blue", size / 10);
               zChar.position = new BABYLON.Vector3(0, 0.05 * size, 0.9 * size);
               var zChar1 = makeTextPlane("-Z", "blue", size / 10);
               zChar1.position = new BABYLON.Vector3(0, 0.05 * size, -0.9 * size);
            };
            showAxis(10);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Vector

讓我們定義沿x、y和z軸的座標。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3( .5, .5, .5);

            // camera
            var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, new BABYLON.Vector3(5, 3, 0), scene);
            camera.setPosition(new BABYLON.Vector3(5, 10, -10));
            camera.attachControl(canvas, true);
            
            // lights
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 0.5, 0), scene);
            light.intensity = 0.8;
            var spot = new BABYLON.SpotLight(
               "spot", new BABYLON.Vector3(25, 15, -10), 
               new BABYLON.Vector3(-1, -0.8, 1), 15, 1, scene);
            spot.diffuse = new BABYLON.Color3(1, 1, 1);
            spot.specular = new BABYLON.Color3(0, 0, 0);
            spot.intensity = 0.2; 
            
            // material
            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(0.5, 0.5, 1.0);
            mat.backFaceCulling = false;
            
            //mat.wireframe = true;
            var makeTextPlane = function(text, color, size) {
               var dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", 50, scene, true);
               dynamicTexture.hasAlpha = true;
               dynamicTexture.drawText(text, 5, 40, "bold 36px Arial", color , "transparent", true);
               
               var plane = new BABYLON.Mesh.CreatePlane("TextPlane", size, scene, true);
               plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial", scene);
               plane.material.backFaceCulling = false;
               plane.material.specularColor = new BABYLON.Color3(0, 0, 0);
               plane.material.diffuseTexture = dynamicTexture;
               return plane;
            };
            
            // show axis
            var showAxis = function(size) {
               var axisX = BABYLON.Mesh.CreateLines("axisX", [ 
                  new BABYLON.Vector3(-size * 0.95, 0.05 * size, 0),
                  new BABYLON.Vector3(-size, 0, 0), 
                  new BABYLON.Vector3(-size * 0.95, -0.05 * size, 0),
                  new BABYLON.Vector3(-size, 0, 0),
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(size, 0, 0), 
                  new BABYLON.Vector3(size * 0.95, 0.05 * size, 0), 
                  new BABYLON.Vector3(size, 0, 0), 
                  new BABYLON.Vector3(size * 0.95, -0.05 * size, 0)
               ], scene);
               axisX.color = new BABYLON.Color3(1, 0, 0);
               var xChar = makeTextPlane("X", "red", size / 10);
               xChar.position = new BABYLON.Vector3(0.9 * size, -0.05 * size, 0);

               var xChar1 = makeTextPlane("-X", "red", size / 10);
               xChar1.position = new BABYLON.Vector3(-0.9 * size, 0.05 * size, 0);
               var xcor = [];
               for (i =- 10; i <= 10; i++) {
                  xcor[i] = makeTextPlane(i, "red", size / 10);
                  xcor[i].position = new BABYLON.Vector3(i, 0, 0);
               }

               var axisY = BABYLON.Mesh.CreateLines("axisY", [
                  new BABYLON.Vector3( -0.05 * size, -size * 0.95, 0),
                  new BABYLON.Vector3(0, -size, 0),
                  new BABYLON.Vector3(0.05 * size, -size * 0.95, 0),
                  new BABYLON.Vector3(0, -size, 0), 
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(0, size, 0), 
                  new BABYLON.Vector3( -0.05 * size, size * 0.95, 0), 
                  new BABYLON.Vector3(0, size, 0), 
                  new BABYLON.Vector3( 0.05 * size, size * 0.95, 0)
               ], scene);
               
               axisY.color = new BABYLON.Color3(0, 1, 0);
               var yChar = makeTextPlane("Y", "green", size / 10);
               yChar.position = new BABYLON.Vector3(0, 0.9 * size, -0.05 * size);
               var yChar1 = makeTextPlane("-Y", "green", size / 10);
               yChar1.position = new BABYLON.Vector3(0, -0.9 * size, 0.05 * size);

               var ycor = [];
               for (y=-10;y<=10;y++) {
                  xcor[y] = makeTextPlane(y, "green", size / 10);
                  xcor[y].position = new BABYLON.Vector3(0, y, 0);
               }		

               var axisZ = BABYLON.Mesh.CreateLines("axisZ", [
                  new BABYLON.Vector3( 0 , -0.05 * size, -size * 0.95), 
                  new BABYLON.Vector3(0, 0, -size),
                  new BABYLON.Vector3( 0 , 0.05 * size, -size * 0.95),
                  new BABYLON.Vector3(0, 0, -size), 
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(0, 0, size), 
                  new BABYLON.Vector3( 0 , -0.05 * size, size * 0.95),
                  new BABYLON.Vector3(0, 0, size), 
                  new BABYLON.Vector3( 0, 0.05 * size, size * 0.95)
               ], scene);
               
               axisZ.color = new BABYLON.Color3(0, 0, 1);
               var zChar = makeTextPlane("Z", "blue", size / 10);
               zChar.position = new BABYLON.Vector3(0, 0.05 * size, 0.9 * size);
               var zChar1 = makeTextPlane("-Z", "blue", size / 10);
               zChar1.position = new BABYLON.Vector3(0, 0.05 * size, -0.9 * size);

               var zcor = [];
               for (z =- 10; z <= 10; z++) {
                  xcor[z] = makeTextPlane(z, "green", size / 10);
                  xcor[z].position = new BABYLON.Vector3(0, 0, z);
               }
            };	

            //Lets draw a mesh along the axis.

            var spriteManagerPlayer = new BABYLON.SpriteManager("playerManager", "images/bird.png", 1, 200, scene);
            var player = new BABYLON.Sprite("player", spriteManagerPlayer);
            player.position.x = 2;
            player.position.y = 2;	
            player.position.z = 0;	

            var zChardot = makeTextPlane(".", "red", 1);		
            zChardot.position = new BABYLON.Vector3(1.8, 1.8,0);

            var box = BABYLON.Mesh.CreateBox("box", '2', scene);
            box.position = new BABYLON.Vector3(-5,3,0); // center point of box x-axis is -5 and y axis is 3.

            var box = BABYLON.Mesh.CreateBox("box", '2', scene);
            box.position = new BABYLON.Vector3(0,3,-3); // center point of box x-axis is -5 and y axis is 3.

            var redSphere = BABYLON.Mesh.CreateSphere("red", 32, 1, scene); //no position for sphere so by default it takes 0,0,0
            showAxis(10);
            returnscene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

在本演示中,我們使用了影像bird.png。這些影像儲存在本地images/資料夾中,並在下面提供參考。您可以下載任何您選擇的影像,並在演示連結中使用。

Images/bird.png

Bird

Vetex Coordinates

演示

<!doctype html>
<html>
   <head>
   <meta charset = "utf-8">
   <title>BabylonJs - Basic Element-Creating Scene</title>
   <script src = "babylon.js"></script>
   <style>
   canvas {width: 100%; height: 100%;}
   </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3( .5, .5, .5);

            // camera
            var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, new BABYLON.Vector3(5, 3, 0), scene);
            camera.setPosition(new BABYLON.Vector3(5, 10, -10));
            camera.attachControl(canvas, true);
            
            // lights
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 0.5, 0), scene);
            light.intensity = 0.8;
            
            var spot = new BABYLON.SpotLight(
               "spot", 
               new BABYLON.Vector3(25, 15, -10), 
               new BABYLON.Vector3(-1, -0.8, 1), 15, 1, scene);
            spot.diffuse = new BABYLON.Color3(1, 1, 1);
            spot.specular = new BABYLON.Color3(0, 0, 0);
            spot.intensity = 0.2; 
            
            // material
            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(0.5, 0.5, 1.0);
            mat.backFaceCulling = false;
            
            //mat.wireframe = true;
            var makeTextPlane = function(text, color, size) {
               var dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", 50, scene, true);
               dynamicTexture.hasAlpha = true;
               dynamicTexture.drawText(text, 5, 40, "bold 36px Arial", color , "transparent", true);
               var plane = new BABYLON.Mesh.CreatePlane("TextPlane", size, scene, true);
               plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial", scene);
               plane.material.backFaceCulling = false;
               plane.material.specularColor = new BABYLON.Color3(0, 0, 0);
               plane.material.diffuseTexture = dynamicTexture;
               return plane;
            };
            
            // show axis
            var showAxis = function(size) {	
               var axisX = BABYLON.Mesh.CreateLines("axisX", [ 
                  new BABYLON.Vector3(-size * 0.95, 0.05 * size, 0),
                  new BABYLON.Vector3(-size, 0, 0), 
                  new BABYLON.Vector3(-size * 0.95, -0.05 * size, 0),
                  new BABYLON.Vector3(-size, 0, 0),
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(size, 0, 0), 
                  new BABYLON.Vector3(size * 0.95, 0.05 * size, 0), 
                  new BABYLON.Vector3(size, 0, 0), 
                  new BABYLON.Vector3(size * 0.95, -0.05 * size, 0)], scene);
               axisX.color = new BABYLON.Color3(1, 0, 0);
               var xChar = makeTextPlane("X", "red", size / 10);
               xChar.position = new BABYLON.Vector3(0.9 * size, -0.05 * size, 0);

               var xChar1 = makeTextPlane("-X", "red", size / 10);
               xChar1.position = new BABYLON.Vector3(-0.9 * size, 0.05 * size, 0);
               var xcor = [];
               for (i =- 10; i <= 10; i++) {
                  xcor[i] = makeTextPlane(i, "red", size / 10);
                  xcor[i].position = new BABYLON.Vector3(i, 0, 0);
               }

               var axisY = BABYLON.Mesh.CreateLines("axisY", [
                  new BABYLON.Vector3( -0.05 * size, -size * 0.95, 0),
                  new BABYLON.Vector3(0, -size, 0),
                  new BABYLON.Vector3(0.05 * size, -size * 0.95, 0),
                  new BABYLON.Vector3(0, -size, 0), 
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(0, size, 0), 
                  new BABYLON.Vector3( -0.05 * size, size * 0.95, 0), 
                  new BABYLON.Vector3(0, size, 0), 
                  new BABYLON.Vector3( 0.05 * size, size * 0.95, 0)
               ], scene);
               
               axisY.color = new BABYLON.Color3(0, 1, 0);
               var yChar = makeTextPlane("Y", "green", size / 10);
               yChar.position = new BABYLON.Vector3(0, 0.9 * size, -0.05 * size);
               var yChar1 = makeTextPlane("-Y", "green", size / 10);
               yChar1.position = new BABYLON.Vector3(0, -0.9 * size, 0.05 * size);

               var ycor = [];
               for (y =- 10; y <= 10; y++) {
                  xcor[y] = makeTextPlane(y, "green", size / 10);
                  xcor[y].position = new BABYLON.Vector3(0, y, 0);
               }

               var axisZ = BABYLON.Mesh.CreateLines("axisZ", [
                  new BABYLON.Vector3( 0 , -0.05 * size, -size * 0.95), 
                  new BABYLON.Vector3(0, 0, -size),
                  new BABYLON.Vector3( 0 , 0.05 * size, -size * 0.95),
                  new BABYLON.Vector3(0, 0, -size), 
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(0, 0, size), 
                  new BABYLON.Vector3( 0 , -0.05 * size, size * 0.95),
                  new BABYLON.Vector3(0, 0, size), 
                  new BABYLON.Vector3( 0, 0.05 * size, size * 0.95)
               ], scene);
               axisZ.color = new BABYLON.Color3(0, 0, 1);
               var zChar = makeTextPlane("Z", "blue", size / 10);
               zChar.position = new BABYLON.Vector3(0, 0.05 * size, 0.9 * size);
               var zChar1 = makeTextPlane("-Z", "blue", size / 10);
               zChar1.position = new BABYLON.Vector3(0, 0.05 * size, -0.9 * size);

               var zcor = [];
               for (z =- 10; z <= 10; z++) {
                  xcor[z] = makeTextPlane(z, "green", size / 10);
                  xcor[z].position = new BABYLON.Vector3(0, 0, z);
               }
            };

            var kite = BABYLON.Mesh.CreateLines("kite", [
               new BABYLON.Vector3(-4,0,0),
               new BABYLON.Vector3(0,4,0), 
               new BABYLON.Vector3(4,0,0), 
               new BABYLON.Vector3(0,-4,0),
               new BABYLON.Vector3(-4,0,0)
            ], scene);
            kite.color = new BABYLON.Color3(1, 1, 1);

            var path = [];
            path.push(new BABYLON.Vector3(-4, 0, 0));
            path.push(new BABYLON.Vector3(0, 0, 0));
            path.push(new BABYLON.Vector3(4, 0, 0));

            var lines1 = BABYLON.Mesh.CreateLines("lines",path, scene, true);
            lines1.color = new BABYLON.Color3(1, 1, 1);
            showAxis(10);	
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行將生成以下輸出

Vectormode

向量旋轉

現在讓我們看看向量旋轉是如何工作的。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3( .5, .5, .5);

            // camera
            var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, new BABYLON.Vector3(5, 3, 0), scene);
            camera.setPosition(new BABYLON.Vector3(0, 0, 0));
            camera.attachControl(canvas, true);
            
            // lights
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 0.5, 0), scene);
            light.intensity = 0.8;
            var spot = new BABYLON.SpotLight(
               "spot", 
               new BABYLON.Vector3(25, 15, -10), 
               new BABYLON.Vector3(-1, -0.8, 1), 15, 1, scene);
            spot.diffuse = new BABYLON.Color3(1, 1, 1);
            spot.specular = new BABYLON.Color3(0, 0, 0);
            spot.intensity = 0.2; 
            
            // material
            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(0.5, 0.5, 1.0);
            mat.backFaceCulling = false;
            
            //mat.wireframe = true;
            var makeTextPlane = function(text, color, size) {
               var dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", 50, scene, true);
               dynamicTexture.hasAlpha = true;
               dynamicTexture.drawText(text, 5, 40, "bold 36px Arial", color , "transparent", true);
               var plane = new BABYLON.Mesh.CreatePlane("TextPlane", size, scene, true);
               plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial", scene);
               plane.material.backFaceCulling = false;
               plane.material.specularColor = new BABYLON.Color3(0, 0, 0);
               plane.material.diffuseTexture = dynamicTexture;
               return plane;
            };
            // show axis
            var showAxis = function(size) {
               var axisX = BABYLON.Mesh.CreateLines("axisX", [ 
                  new BABYLON.Vector3(-size * 0.95, 0.05 * size, 0),
                  new BABYLON.Vector3(-size, 0, 0), 
                  new BABYLON.Vector3(-size * 0.95, -0.05 * size, 0),
                  new BABYLON.Vector3(-size, 0, 0),
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(size, 0, 0), 
                  new BABYLON.Vector3(size * 0.95, 0.05 * size, 0), 
                  new BABYLON.Vector3(size, 0, 0), 
                  new BABYLON.Vector3(size * 0.95, -0.05 * size, 0)
               ], scene);
               
               axisX.color = new BABYLON.Color3(1, 0, 0);
               var xChar = makeTextPlane("X", "red", size / 10);
               xChar.position = new BABYLON.Vector3(0.9 * size, -0.05 * size, 0);

               var xChar1 = makeTextPlane("-X", "red", size / 10);
               xChar1.position = new BABYLON.Vector3(-0.9 * size, 0.05 * size, 0);
               var xcor = [];
               for (i =- 10; i <= 10; i++) {
                  xcor[i] = makeTextPlane(i, "red", size / 10);
                  xcor[i].position = new BABYLON.Vector3(i, 0, 0);
               }

               var axisY = BABYLON.Mesh.CreateLines("axisY", [
                  new BABYLON.Vector3( -0.05 * size, -size * 0.95, 0),
                  new BABYLON.Vector3(0, -size, 0),
                  new BABYLON.Vector3(0.05 * size, -size * 0.95, 0),
                  new BABYLON.Vector3(0, -size, 0), 
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(0, size, 0), 
                  new BABYLON.Vector3( -0.05 * size, size * 0.95, 0), 
                  new BABYLON.Vector3(0, size, 0), 
                  new BABYLON.Vector3( 0.05 * size, size * 0.95, 0)
               ], scene);
               
               axisY.color = new BABYLON.Color3(0, 1, 0);
               var yChar = makeTextPlane("Y", "green", size / 10);
               yChar.position = new BABYLON.Vector3(0, 0.9 * size, -0.05 * size);
               var yChar1 = makeTextPlane("-Y", "green", size / 10);
               yChar1.position = new BABYLON.Vector3(0, -0.9 * size, 0.05 * size);

               var ycor = [];
               for (y =- 10; y <= 10; y++) {
                  xcor[y] = makeTextPlane(y, "green", size / 10);
                  xcor[y].position = new BABYLON.Vector3(0, y, 0);
               }

               var axisZ = BABYLON.Mesh.CreateLines("axisZ", [
                  new BABYLON.Vector3( 0 , -0.05 * size, -size * 0.95), 
                  new BABYLON.Vector3(0, 0, -size),
                  new BABYLON.Vector3( 0 , 0.05 * size, -size * 0.95),
                  new BABYLON.Vector3(0, 0, -size), 
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(0, 0, size), 
                  new BABYLON.Vector3( 0 , -0.05 * size, size * 0.95),
                  new BABYLON.Vector3(0, 0, size), 
                  new BABYLON.Vector3( 0, 0.05 * size, size * 0.95)
               ], scene);
               
               axisZ.color = new BABYLON.Color3(0, 0, 1);
               var zChar = makeTextPlane("Z", "blue", size / 10);
               zChar.position = new BABYLON.Vector3(0, 0.05 * size, 0.9 * size);
               var zChar1 = makeTextPlane("-Z", "blue", size / 10);
               zChar1.position = new BABYLON.Vector3(0, 0.05 * size, -0.9 * size);

               var zcor = [];
               for (z =- 10; z <= 10; z++) {
                  xcor[z] = makeTextPlane(z, "green", size / 10);
                  xcor[z].position = new BABYLON.Vector3(0, 0, z);
               }
            };

            var yellowSphere = BABYLON.Mesh.CreateSphere("yellowSphere",32, 1, scene);
            yellowSphere.setPivotMatrix(BABYLON.Matrix.Translation(2, 0, 0));
            var yellowMaterial = new BABYLON.StandardMaterial("yellowMaterial", scene);
            yellowMaterial.diffuseColor = BABYLON.Color3.Yellow();
            yellowSphere.material = yellowMaterial;

            var wheel1 = BABYLON.MeshBuilder.CreateTorus('t1', {diameter: 2.0}, scene);
            wheel1.position.x = -2.0
            wheel1.position.z = -2.0;

            showAxis(10);	
            var k = 0.0;
            var y = 0.0;
            var x = 0.0;
            scene.registerBeforeRender(function () {
               wheel1.rotation.copyFromFloats(0.0, 0.0, Math.PI / 2);
               wheel1.addRotation(0.0, y, 0.0); 
               wheel1.addRotation(x, 0.0, 0.0);
               yellowSphere.rotation.y += 0.01;
               y += 0.05; 
            });	
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Vector Rotate

BabylonJS - 貼花

貼花就像貼在物體上的貼紙。貼紙繪製是藉助繪製在網格上的二維影像完成的(例如,遊戲中的物體)。在遊戲中,假設有一支軍隊正在射擊子彈,需要在物體上看到子彈的痕跡。所以在Babylon.js中,它是使用貼花完成的,當您點選任何物體時,您將在點選的位置繪製一個二維影像。

貼花用於在建立的網格上新增細節——例如子彈、孔洞等細節。在下面給出的演示連結中,我們使用影像並將其新增到匯入的網格中。

要新增貼花,可以使用以下程式碼:

var newDecal = BABYLON.Mesh.CreateDecal("decal", mesh, decalPosition, normal, decalSize, angle);

執行以下程式碼以在網格上新增貼花:

BABYLON.SceneLoader.ImportMesh("Shcroendiger'scat", "scenes/", "SSAOcat.babylon", scene, function (newMeshes) {
   var cat = newMeshes[0]; / /this is mesh shown on the screen.

   // Set the target of the camera to the first imported mesh
   camera.target = cat;

   var decalMaterial = new BABYLON.StandardMaterial("decalMat", scene);
   decalMaterial.diffuseTexture = new BABYLON.Texture("images/impact1.jpg", scene);
   decalMaterial.diffuseTexture.hasAlpha = true;
   decalMaterial.zOffset = -2;

   var onPointerDown = function (evt) {
      if (evt.button !== 0) {
         return;
      }

      // check if we are under a mesh
      var pickInfo = scene.pick(scene.pointerX, scene.pointerY, function (mesh) { return mesh === cat; 
      // this will give all the meshes , but it will pick the mesh whch is same as cat and return true if it is found });
      if (pickInfo.hit) { // if true
         var decalSize = new BABYLON.Vector3(5, 5, 5); //size of decal is defined

         var newDecal = BABYLON.Mesh.CreateDecal("decal", cat, pickInfo.pickedPoint, pickInfo.getNormal(true), decalSize); //decal is created 
         newDecal.material = decalMaterial; //decal material is added.
      }
   }
   var canvas = engine.getRenderingCanvas();
   canvas.addEventListener("pointerdown", onPointerDown, false);

   scene.onDispose = function () {
      canvas.removeEventListener("pointerdown", onPointerDown);
   }
});

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            //Adding a light
            var light = new BABYLON.HemisphericLight("Hemi", new BABYLON.Vector3(0, 1, 0), scene);

            //Adding an Arc Rotate Camera
            var camera = new BABYLON.ArcRotateCamera("Camera", -1.85, 1.2, 200, BABYLON.Vector3.Zero(), scene);

            camera.attachControl(canvas, true);

            // The first parameter can be used to specify which mesh to import. Here we import all meshes
            BABYLON.SceneLoader.ImportMesh("Shcroendiger'scat", "scenes/", "SSAOcat.babylon", scene, function (newMeshes) {
               var cat = newMeshes[0];

               // Set the target of the camera to the first imported mesh
               camera.target = cat;

               var decalMaterial = new BABYLON.StandardMaterial("decalMat", scene);
               decalMaterial.diffuseTexture = new BABYLON.Texture("images/impact1.jpg", scene);
               decalMaterial.diffuseTexture.hasAlpha = true;
               decalMaterial.zOffset = -2;

               var onPointerDown = function (evt) {
                  if (evt.button !== 0) {
                     return;
                  }

                  // check if we are under a mesh
                  var pickInfo = scene.pick(scene.pointerX, scene.pointerY, function (mesh) { return mesh === cat; });
                  if (pickInfo.hit) {
                     var decalSize = new BABYLON.Vector3(5, 5, 5);

                     var newDecal = BABYLON.Mesh.CreateDecal("decal", cat, pickInfo.pickedPoint, pickInfo.getNormal(true), decalSize);
                     newDecal.material = decalMaterial;
                  }
               }
               var canvas = engine.getRenderingCanvas();
               canvas.addEventListener("pointerdown", onPointerDown, false);

               scene.onDispose = function () {
                  canvas.removeEventListener("pointerdown", onPointerDown);
               }
            });	
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

在上面的演示連結中,我們使用了SSAOcat.babylon網格。您可以從此處下載SSAOcat.babylon的json檔案:

SSAOcat.babylon

將檔案儲存在scenes/資料夾中。這將幫助您獲得如下所示的輸出。

輸出

以上程式碼行生成以下輸出:

Decals

在本演示中,我們使用了影像impact1.jpg。這些影像儲存在本地images/資料夾中,並在下面提供參考。您可以下載任何您選擇的影像,並在演示連結中使用。

images/impact1.jpg

Impact1

BabylonJS - Curve3

BabylonJS具有內建API,可以建立一些複雜的數學曲線。我們之前已經看到過使用複雜方程式建立的條帶、線條,用於繪製圖案並計算給定網格的路徑座標。我們這裡有一個內建的API來避免進行復雜的計算,就像在Curves API中一樣。

解釋的曲線如下:

  • 二次貝塞爾曲線
  • 三次貝塞爾曲線
  • 埃爾米特樣條曲線
  • Catmull-Rom樣條曲線

二次貝塞爾曲線

在本節中,我們將學習二次貝塞爾曲線。

語法

var bezier = BABYLON.Curve3.CreateQuadraticBezier(origin, control, destination, nb_of_points);

引數

考慮與二次貝塞爾曲線相關的以下引數。

  • 起點 - 曲線的起點。

  • 控制點 - 曲線的控制點。

  • 終點 - 終點。

  • 點數 - 陣列中的點數。

三次貝塞爾曲線

在本節中,我們將學習三次貝塞爾曲線。

語法

var bezier3 = BABYLON.Curve3.CreateCubicBezier(origin, control1, control2, destination, nb_of_points)

引數

考慮與三次貝塞爾曲線相關的以下引數。

  • 起點 - 起點。

  • 控制點1 - 第一個控制點(向量形式)。

  • 控制點2 - 第二個控制點(向量形式)。

  • 終點 - 終點(向量形式)。

  • 點數 - 陣列形式的點數。

埃爾米特樣條曲線

在本節中,我們將學習埃爾米特樣條曲線。

語法

var hermite = BABYLON.Curve3.CreateHermiteSpline(p1, t1, p2, t2, nbPoints);

引數

考慮與埃爾米特樣條曲線相關的以下引數:

  • p1 - 曲線的起點。

  • t1 - 起點切向量點。

  • p2 - 終點。

  • t2 - 終點切向量。

  • 點數 - 最終曲線的點陣列。

Catmull-Rom樣條曲線

在本節中,我們將學習Catmull-Rom樣條曲線。

語法

var nbPoints = 20;   // the number of points between each Vector3 control points
var points = [vec1, vec2, ..., vecN];  // an array of Vector3 the curve must pass through : the control points
var catmullRom = BABYLON.Curve3.CreateCatmullRomSpline(points, nbPoints);

引數

考慮與Catmull-Rom樣條曲線相關的以下引數:

  • - Vector3陣列,曲線必須透過控制點。

  • 點數 - 每個Vector3控制點之間的點數。

var path = catmullRom.getPoints(); // getPoints() returns an array of successive Vector3.
var l = catmullRom.length(); // method returns the curve length.

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3( .5, .5, .5);

            // camera
            var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, new BABYLON.Vector3(5, 3, 0), scene);
            camera.setPosition(new BABYLON.Vector3(0, 0, -100));
            camera.attachControl(canvas, true);
            
            // lights
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 0.5, 0), scene);
            light.intensity = 0.8;
            var spot = new BABYLON.SpotLight(
            "spot", 
            new BABYLON.Vector3(25, 15, -10), 
            new BABYLON.Vector3(-1, -0.8, 1), 15, 1, scene);
            spot.diffuse = new BABYLON.Color3(1, 1, 1);
            spot.specular = new BABYLON.Color3(0, 0, 0);
            spot.intensity = 0.2; 
            
            // material
            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(0.5, 0.5, 1.0);
            mat.backFaceCulling = false;
            
            //mat.wireframe = true;
            var makeTextPlane = function(text, color, size) {
               var dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", 50, scene, true);
               dynamicTexture.hasAlpha = true;
               dynamicTexture.drawText(text, 5, 40, "bold 36px Arial", color , "transparent", true);
               
               var plane = new BABYLON.Mesh.CreatePlane("TextPlane", size, scene, true);
               
               plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial", scene);
               plane.material.backFaceCulling = false;
               plane.material.specularColor = new BABYLON.Color3(0, 0, 0);
               plane.material.diffuseTexture = dynamicTexture;
               return plane;
            };
            
            // show axis
            var showAxis = function(size) { 
               var axisX = BABYLON.Mesh.CreateLines("axisX", [ 
                  new BABYLON.Vector3(-size * 0.95, 0.05 * size, 0),
                  new BABYLON.Vector3(-size, 0, 0), 
                  new BABYLON.Vector3(-size * 0.95, -0.05 * size, 0),
                  new BABYLON.Vector3(-size, 0, 0),
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(size, 0, 0), 
                  new BABYLON.Vector3(size * 0.95, 0.05 * size, 0), 
                  new BABYLON.Vector3(size, 0, 0), 
                  new BABYLON.Vector3(size * 0.95, -0.05 * size, 0)
               ], scene);
               
               axisX.color = new BABYLON.Color3(1, 0, 0);
               var xChar = makeTextPlane("X", "red", size / 10);
               xChar.position = new BABYLON.Vector3(0.9 * size, -0.05 * size, 0);			
               
               var xChar1 = makeTextPlane("-X", "red", size / 10);
               xChar1.position = new BABYLON.Vector3(-0.9 * size, 0.05 * size, 0);
               
               var xcor = [];
               for (i =- 20; i <= 20; i++) {
                  xcor[i] = makeTextPlane(i, "red", size / 10);
                  xcor[i].position = new BABYLON.Vector3(i, 0, 0);
               }
               
               var axisY = BABYLON.Mesh.CreateLines("axisY", [
                  new BABYLON.Vector3( -0.05 * size, -size * 0.95, 0),
                  new BABYLON.Vector3(0, -size, 0),
                  new BABYLON.Vector3(0.05 * size, -size * 0.95, 0),
                  new BABYLON.Vector3(0, -size, 0),
                  new BABYLON.Vector3.Zero(),
                  new BABYLON.Vector3(0, size, 0), 
                  new BABYLON.Vector3( -0.05 * size, size * 0.95, 0), 
                  new BABYLON.Vector3(0, size, 0), 
                  new BABYLON.Vector3( 0.05 * size, size * 0.95, 0)
               ], scene);
               
               axisY.color = new BABYLON.Color3(0, 1, 0);
               var yChar = makeTextPlane("Y", "green", size / 10);
               yChar.position = new BABYLON.Vector3(0, 0.9 * size, -0.05 * size);
               var yChar1 = makeTextPlane("-Y", "green", size / 10);
               yChar1.position = new BABYLON.Vector3(0, -0.9 * size, 0.05 * size);
               var ycor = [];
               for (y =- 20; y <= 20; y++) {
                  xcor[y] = makeTextPlane(y, "green", size / 10);
                  xcor[y].position = new BABYLON.Vector3(0, y, 0);
               }


               var axisZ = BABYLON.Mesh.CreateLines("axisZ", [
                  new BABYLON.Vector3( 0 , -0.05 * size, -size * 0.95), 
                  new BABYLON.Vector3(0, 0, -size),
                  new BABYLON.Vector3( 0 , 0.05 * size, -size * 0.95),
                  new BABYLON.Vector3(0, 0, -size), 
                  new BABYLON.Vector3.Zero(), 
                  new BABYLON.Vector3(0, 0, size), 
                  new BABYLON.Vector3( 0 , -0.05 * size, size * 0.95),
                  new BABYLON.Vector3(0, 0, size), 
                  new BABYLON.Vector3( 0, 0.05 * size, size * 0.95)
               ], scene);
               axisZ.color = new BABYLON.Color3(0, 0, 1);
               var zChar = makeTextPlane("Z", "blue", size / 10);
               zChar.position = new BABYLON.Vector3(0, 0.05 * size, 0.9 * size);
               var zChar1 = makeTextPlane("-Z", "blue", size / 10);
               zChar1.position = new BABYLON.Vector3(0, 0.05 * size, -0.9 * size);

               var zcor = [];
               for (z =- 20; z <= 20; z++) {
                  xcor[z] = makeTextPlane(z, "green", size / 10);
                  xcor[z].position = new BABYLON.Vector3(0, 0, z);
               }
            };

            var quadraticBezierVectors = BABYLON.Curve3.CreateQuadraticBezier( 
            BABYLON.Vector3.Zero(), 
            new BABYLON.Vector3(10, 5, 5), 
            new BABYLON.Vector3(5, 10, 0), 15);
            var quadraticBezierCurve = BABYLON.Mesh.CreateLines("qbezier", quadraticBezierVectors.getPoints(), scene);
            quadraticBezierCurve.color = new BABYLON.Color3(1, 1, 0.5);

            var cubicBezierVectors = BABYLON.Curve3.CreateCubicBezier( 
            BABYLON.Vector3.Zero(), 
            new BABYLON.Vector3(10, 5, 20), 
            new BABYLON.Vector3(-50, 5, -20), 
            new BABYLON.Vector3( -10, 20, 10), 60);
            var cubicBezierCurve = BABYLON.Mesh.CreateLines("cbezier", cubicBezierVectors.getPoints(), scene);
            cubicBezierCurve.color = new BABYLON.Color3(1, 0, 0);

            var continued = cubicBezierVectors.continue(cubicBezierVectors).continue(quadraticBezierVectors);

            var points = continued.getPoints();
            var nbPoints = 60;
            var l = continued.length() / 2;
            var p1 = points[points.length - 1];
            var t1 = (p1.subtract(points[points.length - 2])).scale(l);
            var p2 = points[0];
            var t2 = (points[1].subtract(p2)).scale(l);

            var hermite = BABYLON.Curve3.CreateHermiteSpline(p1, t1, p2, t2, nbPoints);

            continued = continued.continue(hermite);

            var points = continued.getPoints();
            var continuedCurve = BABYLON.Mesh.CreateLines("continued", points, scene);
            continuedCurve.position = new BABYLON.Vector3(20, -20, 20);
            continuedCurve.color = new BABYLON.Color3(0, 0, 0);

            var nbPoints = 20;                     // the number of points between each Vector3 control points
            var points = [new BABYLON.Vector3(10, 5, 20), 
            new BABYLON.Vector3(-20, 5, -20), 
            new BABYLON.Vector3(-25, 5, -20), 
            new BABYLON.Vector3( -30, 20, 10),];  // an array of Vector3 the curve must pass through : the control points
            var catmullRom = BABYLON.Curve3.CreateCatmullRomSpline(points, nbPoints);

            var path = catmullRom.getPoints();
            var l = catmullRom.length();

            var finalcatmullCurve = BABYLON.Mesh.CreateLines("continued", path, scene);

            var mySinus = [];
            for (var i = 0; i < 30; i++) {
               mySinus.push( new BABYLON.Vector3(i, Math.sin(i / 10), 0) );
            }

            var mySinusCurve3 = new BABYLON.Curve3(mySinus);
            var myFullCurve = mySinusCurve3.continue(cubicBezierVectors).continue(quadraticBezierVectors);
            var points1 = myFullCurve.getPoints();
            var curve3d = BABYLON.Mesh.CreateLines("continued", points1, scene);
            curve3d.color = new BABYLON.Color3(0.9, 1, 0.2);
            showAxis(20);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行將生成以下輸出:

Catmull-Rom Spline Curve

BabylonJS - 動態紋理

BabylonJS的動態紋理建立一個畫布,您可以輕鬆地在紋理上寫入文字。它還允許您使用畫布並使用html5畫布的所有功能與動態紋理一起使用。

我們將研究一個示例,該示例將顯示如何在紋理上寫入文字,還將在我們建立的網格上繪製貝塞爾曲線。

語法

以下是建立動態紋理的語法:

var myDynamicTexture = new BABYLON.DynamicTexture(name, option, scene);

引數

以下是建立動態紋理所需的引數:

  • 名稱 - 動態紋理的名稱

  • 選項 - 將具有動態紋理的寬度和高度

  • 場景 - 建立的場景

語法

以下是如何在紋理上寫入文字的語法:

myDynamicTexture.drawText(text, x, y, font, color, canvas color, invertY, update);

引數

以下是如何在紋理上寫入文字所需的引數:

  • 文字 - 要寫入的文字;

  • x - 距左邊緣的距離;

  • y - 距頂部或底部的距離,取決於invertY;

  • 字型 - 以字型樣式、字型大小、字型名稱形式表示的字型定義;

  • invertY - 預設情況下為true,在這種情況下,y是距頂部的距離,當為false時,y是距底部的距離,字母反轉;

  • 更新 - 預設情況下為true,動態紋理將立即更新。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>MDN Games: Babylon.js demo - shapes</title>
      <script src = "https://end3r.github.io/MDN-Games-3D/Babylon.js/js/babylon.js"></script>    
      <style>
         html,body,canvas { margin: 0; padding: 0; width: 100%; height: 100%; font-size: 0; }
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI/2, Math.PI / 3, 25, BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, true);

            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;	

            var box = BABYLON.Mesh.CreateBox("box", 3.0, scene);
            box.position = new BABYLON.Vector3(0, 0, -5); 

            //Create dynamic texture		
            var textureGround = new BABYLON.DynamicTexture("dynamic texture", {width:512, height:256}, scene);   
            var textureContext = textureGround.getContext();

            var materialGround = new BABYLON.StandardMaterial("Mat", scene);    				
            materialGround.diffuseTexture = textureGround;
            box.material = materialGround;

            //Add text to dynamic texture
            var font = "bold 60px Arial";
            textureGround.drawText("Box", 200, 150, font, "green", "white", true, true);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Dynamic Texture

動態紋理還允許如下使用html5畫布方法和屬性:

語法

var ctx = myDynamicTexture.getContext();

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title> Babylon.JS : Demo2</title>
      <script src = "babylon.js"></script>   
      <style>
         canvas { width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);	
         var createScene = function () {
            var scene = new BABYLON.Scene(engine);

            var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI/2, Math.PI / 3, 25, BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, true);

            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;		

            var ground = BABYLON.MeshBuilder.CreateGround("ground1", {width: 20, height: 10, subdivisions: 25}, scene);

            //Create dynamic texture
            var textureGround = new BABYLON.DynamicTexture("dynamic texture", 512, scene);   
            var textureContext = textureGround.getContext();

            var materialGround = new BABYLON.StandardMaterial("Mat", scene);    				
            materialGround.diffuseTexture = textureGround;
            ground.material = materialGround;

            //Draw on canvas
            textureContext.beginPath();
            textureContext.moveTo(75,40);
            textureContext.bezierCurveTo(75,37,70,25,50,25);
            textureContext.bezierCurveTo(20,25,20,62.5,20,62.5);
            textureContext.bezierCurveTo(20,80,40,102,75,120);
            textureContext.bezierCurveTo(110,102,130,80,130,62.5);
            textureContext.bezierCurveTo(130,62.5,130,25,100,25);
            textureContext.bezierCurveTo(85,25,75,37,75,40);
            textureContext.fillStyle = "red";
            textureContext.fill();
            textureGround.update();
            
            return scene;
         };
         var scene = createScene();
            engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Dynamic Texture1

解釋

我們建立了地面網格並向其添加了動態紋理。

//ground mesh
var ground = BABYLON.MeshBuilder.CreateGround("ground1", {width: 20, height: 10, subdivisions: 25}, scene);

//Create dynamic texture
var textureGround = new BABYLON.DynamicTexture("dynamic texture", 512, scene);   

//adding dynamic texture to ground using standard material
var materialGround = new BABYLON.StandardMaterial("Mat", scene);    			
materialGround.diffuseTexture = textureGround;
ground.material = materialGround;

要在動態紋理上使用畫布,我們需要先呼叫畫布方法:

var textureContext = textureGround.getContext()

對於畫布,我們將新增貝塞爾曲線,如下所示:

textureContext.beginPath();
textureContext.moveTo(75,40);

textureContext.bezierCurveTo(75,37,70,25,50,25);
textureContext.bezierCurveTo(20,25,20,62.5,20,62.5);
textureContext.bezierCurveTo(20,80,40,102,75,120);
textureContext.bezierCurveTo(110,102,130,80,130,62.5);
textureContext.bezierCurveTo(130,62.5,130,25,100,25);
textureContext.bezierCurveTo(85,25,75,37,75,40);

textureContext.fillStyle = "red";
textureContext.fill();
textureGround.update();

BabylonJS -視差貼圖

視差貼圖也稱為偏移貼圖。它使用高度圖,該高度圖作為材質紋理的偏移量應用,以增強幾何體表面浮雕效果。在3D世界中,應用深度的石牆將具有更明顯的外觀,並且對終端使用者來說看起來更逼真。在較陡峭的視角下,紋理座標的位移更大,由於視差效應,隨著檢視的變化,會產生深度的錯覺。

視差貼圖與標準材質一起使用。我們在標準材質章節中學習了這一點。

視差貼圖具有3個屬性。

  • material.useParallax = true; - 這將啟用視差貼圖。要使用此屬性,需要首先將凹凸紋理分配給材質。

  • material.useParallaxOcclusion = true; - 要使用此屬性,必須將useParallax設定為true。它啟用視差遮擋。

  • material.parallaxScaleBias = 0.1; - 為要分配給網格的深度應用縮放因子。對於視差,介於0.05和0.1之間的值很好。對於遮擋,您可以達到0.2。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            // This creates a basic Babylon Scene object (non-mesh)
            var scene = new BABYLON.Scene(engine);

            // This creates and positions a free camera (non-mesh)
            var camera = new BABYLON.ArcRotateCamera("camera1", 0, Math.PI / 2, 100, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, false);

            // This targets the camera to scene origin
            camera.setTarget(BABYLON.Vector3.Zero());

            // This creates a light, aiming 0,1,0 - to the sky (non-mesh)
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

            // Default intensity is 1. Let's dim the light a small amount
            light.intensity = 0.7;

            var mesh = BABYLON.Mesh.CreateBox("box01", 25, scene);
            mesh.position = new BABYLON.Vector3(0, 0, 0);

            var brickWallDiffURL = "images/a1.png";
            var brickWallNHURL = "images/a2.png";
            var stoneDiffURL = "images/pebble.jpg";
            var stoneNHURL = "images/a3.png";

            var stoneDiffuseTexture = new BABYLON.Texture(stoneDiffURL, scene);
            
            var stoneNormalsHeightTexture = new BABYLON.Texture(stoneNHURL, scene);
            
            var wallDiffuseTexture = new BABYLON.Texture(brickWallDiffURL, scene);
            
            var wallNormalsHeightTexture = new BABYLON.Texture(brickWallNHURL, scene);
            
            var normalsHeightTexture = stoneNormalsHeightTexture;

            var material = new BABYLON.StandardMaterial("mtl01", scene);
            material.diffuseTexture = stoneDiffuseTexture;
            material.bumpTexture = stoneNormalsHeightTexture;
            
            material.useParallax = true;
            material.useParallaxOcclusion = true;
            material.parallaxScaleBias = 0.1;
            material.specularPower = 1000.0;
            material.specularColor = new BABYLON.Color3(0.5, 0.5, 0.5);
            mesh.material = material;	
            return scene;		
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行將生成以下輸出:

Parallex Mapping

在本演示中,我們使用了影像a1.png、a2.png、pebble.jpga3.png。這些影像儲存在本地images/資料夾中,並在下面提供參考。您可以下載任何您選擇的影像,並在演示連結中使用。

Images/a1.png

A1 Wall

Images/a2.png

A2 Wall

Images/pebble.jpg

A1 Wall

images/a3.png

A3 Wall

BabylonJS - 鏡頭光暈

當光線散射並落在影像上時,您會看到外觀不同的影像,顏色也會發生變化。當您開發遊戲以顯示光線效果的真實發生時,會使用鏡頭光暈。考慮一下陽光照射在鏡子上的情況,看到的效果大多被稱為鏡頭光暈。

語法

以下是建立鏡頭光暈的語法:

var lensFlareSystem = new BABYLON.LensFlareSystem("lensFlareSystem", light0, scene);

引數

考慮建立鏡頭光暈的以下引數:

  • 名稱 - 給鏡頭光暈系統起的名字。

  • 光源 - 這可以是光源或相機。

  • 場景 - 將新增鏡頭光暈的場景。

要向場景新增光暈,請執行以下命令:

var flare1 = new BABYLON.LensFlare(0.5, 0.15, new BABYLON.Color3(1, 1, 1), "images/sun1.png", lensFlareSystem);
  • 大小 - 介於0和1之間的浮點值。

  • 位置 - 鏡頭光暈的源(發射器)(它可以是相機、光源或網格)。

  • 鏡頭光暈系統 - 使用鏡頭光暈系統類建立的物件。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = BABYLON.Color3.Gray();
            var camera = new BABYLON.ArcRotateCamera(
               "Camera", -Math.PI / 2, 1.5, 15, BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, false);

            var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, -1, 0), scene);
            light1.groundColor = new BABYLON.Color3(0.2, 0.2, 0.2);
            light1.intensity = 0.5;
            
            var bigdiamond = BABYLON.Mesh.CreateSphere("sphere", 32,6, scene);
            bigdiamond.visibility = 0.6;
            var dmat = new BABYLON.StandardMaterial("dmat", scene);
            dmat.diffuseColor = BABYLON.Color3.Blue();
            
            var texture = new BABYLON.Texture("images/earth.jpg", scene);
            dmat.diffuseTexture = texture;		
            dmat.specularColor = BABYLON.Color3.White();
            bigdiamond.material = dmat;

            var lensflare1 = new BABYLON.LensFlareSystem("lensFlareSystem", camera, scene);
            var flare1 = new BABYLON.LensFlare(
               Math.random(), 0.15, new BABYLON.Color3(1, 1, 1), "images/sun1.png", lensflare1);

            var lensflare2 = new BABYLON.LensFlareSystem("lensFlareSystem", camera, scene);
            var flare2 = new BABYLON.LensFlare(
               Math.random()/2, 0.1, new BABYLON.Color3(1, 0, 0), "images/sun1.png", lensflare2);

            var lensflare3 = new BABYLON.LensFlareSystem("lensFlareSystem", camera, scene);
            var flare3 = new BABYLON.LensFlare(
               Math.random()/8, 0.1, new BABYLON.Color3(1, 0, 1), "images/sun1.png", lensflare3);

            var lensflare4 = new BABYLON.LensFlareSystem("lensFlareSystem", camera, scene);
            var flare4 = new BABYLON.LensFlare(
               Math.random()/12, 0.1, new BABYLON.Color3(0, 1, 0), "images/sun1.png", lensflare4);

            scene.registerBeforeRender(function() {
               scene.getCameraByID("Camera").alpha += 0.01;
            });		
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Lens Flares

earth.jpg

earth

images/sun1.png

sun1

BabylonJS - 建立螢幕截圖

要捕獲您當前正在工作的螢幕,無法使用列印螢幕按鍵高解析度截圖。BabylonJS提供createscreenshot API,可以幫助您做到這一點。它將檔案儲存為png格式,並且影像質量不會降低。

語法

要對螢幕進行截圖,我們需要提供引擎、相機和大小,如下所示。

BABYLON.Tools.CreateScreenshot(engine, camera, { width: 1024, height: 300 }, function (data) {
   var img = document.createElement("img");
   img.src = data;
   document.body.appendChild(img);	
});

新增一個按鈕,當用戶點選它時呼叫截圖API。

對傳遞給截圖API的引擎進行了更改。

var engine = new BABYLON.Engine(canvas, true, { 
   preserveDrawingBuffer: true, stencil: true 
});	

它需要將preserveDrawingBufferstencil設定為true的選項。

按鈕新增如下:

ssButton = document.createElement("input");
document.body.appendChild (ssButton);

將點選事件新增到上面的按鈕,並呼叫createscreenshot。它將在螢幕末尾更新螢幕截圖。用於影像src的資料具有建立的螢幕截圖URL。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });	
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            
            // Setup environment
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 0.5, 0), scene);
            
            var camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 0.8, 20, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var gmat = new BABYLON.StandardMaterial("mat1", scene);
            gmat.alpha = 1.0;
            
            //gmat.diffuseColor = new BABYLON.Color3(1, 0, 0);
            var texture = new BABYLON.Texture("images/mat.jpg", scene);
            gmat.diffuseTexture = texture;

            var ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 150, height:15}, scene);
            ground.material = gmat;

            var mat = new BABYLON.StandardMaterial("mat1", scene);
            mat.alpha = 1.0;
            mat.diffuseColor = new BABYLON.Color3(1, 0, 0);
            
            var texture = new BABYLON.Texture("images/rugby.jpg", scene);
            mat.diffuseTexture = texture;

            var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2, diameterX: 3}, scene);
            sphere.position= new BABYLON.Vector3(15,1,0);
            sphere.material = mat;

            var faceColors = new Array();
            faceColors[1] = new BABYLON.Color4(0,1,0,1);   // green front

            var matcone = new BABYLON.StandardMaterial("mat1", scene);
            matcone.alpha = 1.0;
            matcone.diffuseColor = new BABYLON.Color3(0.9, 0, 2);
            
            var texture = new BABYLON.Texture("images/cone.jpg", scene);
            matcone.diffuseTexture = texture;

            var cone = BABYLON.MeshBuilder.CreateCylinder("cone", {diameterTop: 0, tessellation: 4}, scene);
            cone.position= new BABYLON.Vector3(12,1,0);
            cone.material = matcone;

            var matplane = new BABYLON.StandardMaterial("matplane", scene);
            matplane.alpha = 1.0;
            matplane.diffuseColor = new BABYLON.Color3(0.9, 0, 2);
            
            var texture = new BABYLON.Texture("images/board.jpg", scene);
            matplane.diffuseTexture = texture;
            var plane = BABYLON.MeshBuilder.CreatePlane("plane", {width: 5, height : 5}, scene);
            plane.position= new BABYLON.Vector3(9,2.5,0);
            plane.material = matplane;		
            
            var disc = BABYLON.MeshBuilder.CreateDisc("disc", {tessellation: 3}, scene);
            disc.position= new BABYLON.Vector3(5,1,0);		

            var mattorus = new BABYLON.StandardMaterial("matoct", scene);
            mattorus.alpha = 1.0;
            
            var texture = new BABYLON.Texture("images/ring.jpg", scene);
            mattorus.diffuseTexture = texture;
            
            var torus = BABYLON.MeshBuilder.CreateTorus("torus", {thickness: 0.5}, scene);		
            torus.position= new BABYLON.Vector3(3,1,0);
            torus.material = mattorus;

            var matoct = new BABYLON.StandardMaterial("matoct", scene);
            matoct.alpha = 1.0;
            
            var texture = new BABYLON.Texture("images/d1.png", scene);
            matoct.diffuseTexture = texture;
            var octahedron = BABYLON.MeshBuilder.CreatePolyhedron("oct", {type: 1, size: 3}, scene);
            
            octahedron.position= new BABYLON.Vector3(-2,5,0);
            octahedron.material = matoct;	

            var matico = new BABYLON.StandardMaterial("matico", scene);
            matico.alpha = 1.0;
            
            var texture = new BABYLON.Texture("images/diamond.jpg", scene);
            matico.diffuseTexture = texture;		
            
            var icosphere = BABYLON.MeshBuilder.CreateIcoSphere("ico", {radius: 5, radiusY: 3, subdivisions: 2}, scene);
            icosphere.position= new BABYLON.Vector3(-13,3,0);		
            icosphere.material = matico;		
            
            //add screenshot button
            var ssButton = document.getElementById("takescreenshot");
            if (ssButton == null) {
               ssButton = document.createElement("input");
               document.body.appendChild(ssButton);
            }
            
            ssButton.id = "takescreenshot";
            ssButton.type = "button";
            ssButton.style.position = "fixed";
            ssButton.style.right = "0px";
            ssButton.style.top = "100px";
            ssButton.value = "create screenshot";
            
            ssButton.onclick = function () {
               BABYLON.Tools.CreateScreenshot(engine, camera, { width: 1024, height: 300 },
               function (data) {
                  var img = document.createElement("img");
                  img.src = data;
                  document.body.appendChild(img);
               });
            };			
            return scene;
         }
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });	
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

在本演示中,我們使用了影像mat.jpg、rugby.jpg、cone.jpg、board.jpg、ring.jpg、d1.png、diamond.jpg。這些影像儲存在本地 images/ 資料夾中,並在此下方提供參考。您可以下載任何您選擇的影像,並在演示連結中使用。

Images/mat.jpg

Mat Image

Images/rugby.jpg

rugby Image

Images/cone.jpg

Cone Image

Images/board.jpg

Board Image

Images/ring.jpg

Ring Image

Images/d1.png

D1 Image

Images/diamond.jpg

Diamond Image

BabylonJS - 反射探針

反射探針用於建立類似鏡面的場景。這有助於檢視網格在其上的反射。要建立類似鏡面的場景,您需要呼叫類和所需的網格,您希望在其中看到反射。之後,您需要將網格新增到渲染列表中,如下所示。假設您有一個帶有水面背景的場景,並且需要顯示雲或樹木的反射或飛行的鳥,您可以使用反射探針來實現,並且建立的網格可以新增到渲染列表中,如下所示。

語法

var probe = new BABYLON.ReflectionProbe("main", 512, scene);
probe.renderList.push(yellowSphere);
probe.renderList.push(greenSphere);	
probe.renderList.push(blueSphere);	
probe.renderList.push(mirror);

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            var camera = new BABYLON.ArcRotateCamera("camera1", 0, 0, 10, BABYLON.Vector3.Zero(), scene);

            camera.setPosition(new BABYLON.Vector3(0, 5, -10));
            camera.attachControl(canvas, true);

            camera.upperBetaLimit = Math.PI / 2;
            camera.lowerRadiusLimit = 4;

            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            light.intensity = 0.7;

            var knot = BABYLON.Mesh.CreateTorusKnot("knot", 1, 0.4, 128, 64, 2, 3, scene);

            var yellowSphere = BABYLON.Mesh.CreateSphere("yellowSphere", 16, 1.5, scene);
            yellowSphere.setPivotMatrix(BABYLON.Matrix.Translation(3, 0, 0));

            var blueSphere = BABYLON.Mesh.CreateSphere("blueSphere", 16, 1.5, scene);
            blueSphere.setPivotMatrix(BABYLON.Matrix.Translation(-1, 3, 0));

            var greenSphere = BABYLON.Mesh.CreateSphere("greenSphere", 16, 1.5, scene);
            greenSphere.setPivotMatrix(BABYLON.Matrix.Translation(0, 0, 3));

            // Mirror
            var mirror = BABYLON.Mesh.CreateBox("Mirror", 1.0, scene);
            mirror.scaling = new BABYLON.Vector3(100.0, 0.01, 100.0);
            mirror.material = new BABYLON.StandardMaterial("mirror", scene);
            mirror.material.diffuseTexture = new BABYLON.Texture("images/square.jpg", scene);
            
            mirror.material.diffuseTexture.uScale = 10;
            mirror.material.diffuseTexture.vScale = 10;
            mirror.material.reflectionTexture = new BABYLON.MirrorTexture("mirror", 1024, scene, true);
            
            mirror.material.reflectionTexture.mirrorPlane = new BABYLON.Plane(0, -1.0, 0, -2.0);
            mirror.material.reflectionTexture.renderList = [greenSphere, yellowSphere, blueSphere, knot];
            mirror.material.reflectionTexture.level = 0.5;
            mirror.position = new BABYLON.Vector3(0, -2, 0);	

            // Main material	
            var mainMaterial = new BABYLON.StandardMaterial("main", scene);
            knot.material = mainMaterial;

            var probe = new BABYLON.ReflectionProbe("main", 512, scene);
            probe.renderList.push(yellowSphere);
            probe.renderList.push(greenSphere);	
            probe.renderList.push(blueSphere);	
            probe.renderList.push(mirror);	
            
            mainMaterial.diffuseColor = new BABYLON.Color3(1, 0.5, 0.5);	
            mainMaterial.reflectionTexture = probe.cubeTexture;
            mainMaterial.reflectionFresnel<h3>Parameters</h3> = new BABYLON.Fresnel<h3>Parameters</h3>();
            mainMaterial.reflectionFresnel<h3>Parameters</h3>.bias = 0.02;

            // Fog
            scene.fogMode = BABYLON.Scene.FOGMODE_LINEAR;
            scene.fogColor = scene.clearColor;
            scene.fogStart = 20.0;
            scene.fogEnd = 50.0;

            // Animations
            scene.registerBeforeRender(function () {
               yellowSphere.rotation.y += 0.01;
               greenSphere.rotation.y += 0.01;
               blueSphere.rotation.y += 0.01;
            });
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

Reflection Probes

在本演示中,我們使用了影像square.jpg。這些影像儲存在本地 images/ 資料夾中,並在此下方提供參考。您可以下載任何您選擇的影像,並在演示連結中使用。

images/square.jpg

square

BabylonJS - 標準渲染管線

StandardRenderingPipeline 提供了一組與現實世界相關的後期處理效果。存在不同的後期處理效果,例如燈光效果和照明效果。

在以下示例中,您將看到各種效果,例如鏡頭效果、燈光的後期處理效果等。

它使用 HDR 立方體紋理,並且紋理必須是 .hdr 格式。此紋理提供全景效果,您可以在旋轉相機時看到。

var hdrTexture = new BABYLON.HDRCubeTexture("images/GravelPlaza_REF.hdr", scene, 512);

呼叫標準渲染管線類以使用以下程式碼行獲得效果:

// Create rendering pipeline
var pipeline = new BABYLON.StandardRenderingPipeline("standard", scene, 1.0 / devicePixelRatio, null, [camera]);
pipeline.lensTexture = new BABYLON.Texture("images/lensdirt.jpg", scene)

在下面顯示的演示中,我們將建立 cubetexture 環境。我們將為此使用地面網格,並將標準渲染管線應用於整個場景。

紋理使用 lensTexture 提供,它是一個影像,您可以在移動場景時看到相同的紋理。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 4, Math.PI / 2.5, 200, BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, true);
            camera.minZ = 0.1;

            // Light
            new BABYLON.PointLight("point", new BABYLON.Vector3(0, 40, 0), scene);

            // Environment Texture
            var hdrTexture = new BABYLON.HDRCubeTexture("images/GravelPlaza_REF.hdr", scene, 512);

            // Skybox
            var hdrSkybox = BABYLON.Mesh.CreateBox("hdrSkyBox", 1000.0, scene);
            var hdrSkyboxMaterial = new BABYLON.PBRMaterial("skyBox", scene);
            hdrSkyboxMaterial.backFaceCulling = false;
            hdrSkyboxMaterial.reflectionTexture = hdrTexture.clone();
            hdrSkyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
            hdrSkyboxMaterial.microSurface = 1.0;
            hdrSkyboxMaterial.cameraExposure = 0.6;
            hdrSkyboxMaterial.cameraContrast = 1.6;
            hdrSkyboxMaterial.disableLighting = true;
            hdrSkybox.material = hdrSkyboxMaterial;
            hdrSkybox.infiniteDistance = true;

            // Create mesh
            var woodbox = BABYLON.MeshBuilder.CreateBox("plane", { 
               width: 40, 
               height: 50, 
               depth: 65 
            }, scene);

            var wood = new BABYLON.PBRMaterial("wood", scene);
            wood.reflectionTexture = hdrTexture;
            wood.directIntensity = 1.5;
            wood.environmentIntensity = 0.5;
            wood.specularIntensity = 0.3;
            wood.cameraExposure = 0.9;
            wood.cameraContrast = 1.6;

            wood.reflectivityTexture = new BABYLON.Texture("images/reflectivity.png", scene);
            wood.useMicroSurfaceFromReflectivityMapAlpha = true;

            wood.albedoColor = BABYLON.Color3.White();
            wood.albedoTexture = new BABYLON.Texture("images/albedo.png", scene);
            woodbox.material = wood;

            // Create rendering pipeline
            var pipeline = new BABYLON.StandardRenderingPipeline("standard", scene, 1.0 / devicePixelRatio, null, [camera]);
            pipeline.lensTexture = new BABYLON.Texture("images/lensdirt.jpg", scene);

            // Return scene
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

建立 images 資料夾並將 .hdr 檔案儲存在其中。我們使用了來自www.hdrlabs.com的 images/GravelPlaza_REF.hdr。

您可以下載您選擇的 .hdr 型別檔案,並在演示連結中使用。

輸出

以上程式碼行將生成以下輸出:

Standard Rendering Pipeline

在本演示中,我們使用了影像images/GravelPlaza_REF.hdr、images/reflectivity.png、images/albedo.png、images/lensdirt.jpg。這些影像儲存在本地 images/ 資料夾中,並在此下方提供參考。您可以下載任何您選擇的影像,並在演示連結中使用。請注意,由於 .hdr 檔案大小很大,因此很難在此處貼上它們。

Images/reflectivity.png

Reflectivity

Images/albedo.png

Albedo

Images/lensdirt.png

Lens Dirt

BabylonJS - ShaderMaterial

著色器材質為您提供一個材質作為輸出。您可以將此材質應用於任何網格。它基本上將資料從您的場景傳遞到頂點和片段著色器。

要獲取著色器材質,需要呼叫以下類:

var myShaderMaterial = new BABYLON.ShaderMaterial(name, scene, route, options);

引數

考慮以下與著色器材質相關的引數:

  • 名稱 - 一個字串,命名著色器。

  • 場景 - 使用著色器的場景。

  • 路徑 - 透過以下三種方式之一訪問著色器程式碼的路徑:

object - {
   vertex: "custom", 
   fragment: "custom" 
}, used with 
BABYLON.Effect.ShadersStore["customVertexShader"] and
BABYLON.Effect.ShadersStore["customFragmentShader"]

object - { 
   vertexElement: "vertexShaderCode", 
   fragmentElement: "fragmentShaderCode" 
}, 
used with shader code in <script> tags

string - "./COMMON_NAME", 

最後提到的語法與 index.html 資料夾中的外部檔案 COMMON_NAME.vertex.fx 和 COMMON_NAME.fragment.fx 一起使用。

  • 選項 - 包含屬性和制服陣列的物件,其中包含它們的名稱作為字串。

帶有值的著色器語法如下所示:

var shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, {
   vertex: "custom",
   fragment: "custom",
},
{
   attributes: ["position", "normal", "uv"],
   uniforms: ["world", "worldView", "worldViewProjection", "view", "projection"]
});

屬性必須採用陣列形式。這些包含位置、法線和 uv,它們是 vector3 三維浮點向量。

  • vec2 - 一個二維浮點數向量。

  • vec3 - 一個三維浮點數向量。

  • mat4 - 一個具有 4 列和 4 行浮點數的矩陣。

  • gl_Position - 它提供螢幕座標的位置資料。

  • gl_FragColor - 它提供用於表示螢幕上面的顏色資料。

以上是 GLSL 語言中的內建變數。

由於頂點位置需要儘可能精確,因此所有浮點數都應設定為具有高精度。這是在每個著色器的程式碼開頭使用 – precision highp float 完成的。precision highp float 確定浮點數使用的精度。

以下演示基於第一種物件方法。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         //downloaded HDR files from :http://www.hdrlabs.com/sibl/archive.html
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            var camera = new BABYLON.ArcRotateCamera(
               "Camera", Math.PI / 4, Math.PI / 4, 4, BABYLON.Vector3.Zero(), scene);

            camera.attachControl(canvas, true);

            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

            BABYLON.Effect.ShadersStore["customVertexShader"] = "\r\n" + 
               "precision highp float;\r\n" + 
               "// Attributes\r\n" + 
               "attribute vec3 position;\r\n" + 
               "attribute vec2 uv;\r\n" + 
               "// Uniforms\r\n" + 
               "uniform mat4 worldViewProjection;\r\n" + 

               "// Varying\r\n" + 
               "varying vec2 vUV;\r\n" + 
               "void main(void) {
                  \r\n" + 
                  "gl_Position = worldViewProjection * vec4(position, 1.0);\r\n" + 
                  "vUV = uv;\r\n"+"
               }
               \r\n";
               BABYLON.Effect.ShadersStore["customFragmentShader"] = "\r\n"+
                  "precision highp float;\r\n" + 
                  "varying vec2 vUV;\r\n" + 
                  "uniform sampler2D textureSampler;\r\n" + 
               "void main(void) {
                  \r\n"+
                  "gl_FragColor = texture2D(textureSampler, vUV);\r\n"+"
               }
               \r\n";

            var shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, {
               vertex: "custom",
               fragment: "custom",
            },
            
            {
               attributes: ["position", "normal", "uv"],
               uniforms: ["world", "worldView", "worldViewProjection", "view", "projection"]
            });

            var mainTexture = new BABYLON.Texture("images/mat.jpg", scene);

            shaderMaterial.setTexture("textureSampler", mainTexture);

            shaderMaterial.backFaceCulling = false;

            var box = BABYLON.MeshBuilder.CreateBox("box", {}, scene);
            box.material = shaderMaterial;
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行將生成以下輸出:

Shader Material

在本演示中,我們使用了影像mat.jpg。這些影像儲存在本地 images/ 資料夾中,並在此下方提供參考。您可以下載任何您選擇的影像,並在演示連結中使用。

Images/mat.jpg

Mat Image

BabylonJS - 骨骼和骨架

Babylonjs 提供了建立骨架和骨骼的 API。

語法

現在讓我們看看不同函式的語法。

對於骨架

BABYLON.Skeleton = function (name, id, scene)

對於骨骼

BABYLON.Bone = function (name, skeleton, parentBone, matrix)

骨架和骨骼可以使用 Blender 建立,並且可以匯出為 .babylonjs 格式。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Element-Creating Scene</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);

            //Adding a light
            var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(20, 20, 100), scene);

            //Adding an Arc Rotate Camera
            var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 100, BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, false);

            BABYLON.SceneLoader.ImportMesh(
               "him", "scenes/Dude/", "Dude.babylon", scene, function (newMeshes, particleSystems, skeletons) {
               var dude = newMeshes[0];
               console.log(dude);
               dude.rotation.y = Math.PI;
               dude.position = new BABYLON.Vector3(0, 0, -80);
               scene.beginAnimation(skeletons[0], 0, 100, true, 1.0);
            })
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

在上面的演示連結中,我們使用了 Dude.babylon 網格。您可以從此處下載 Dude.babylon 的 json 檔案:

Dude.babylon

將檔案儲存在 scenes 資料夾中,以獲得如下所示的輸出。

輸出

以上程式碼行生成以下輸出:

Skeletons And Bones

解釋

對於匯入網格,我們使用了 babylonjs dude 網格。

網格為我們提供骨架。例如,skeleton = skeletons[0];

要從骨架中獲取骨骼,請執行以下命令:

skeleton.bones; //it gives a array.

在上面的演示中,我們建立了 2 個球體並傳遞給網格。為此,我們執行了以下命令:

sphere.attachToBone(skeleton.bones[30], dude);

以及:

sphere1.attachToBone(skeleton.bones[40], dude);

attachToBone 是一個函式,您可以將任何網格賦給骨骼。

Skeleton.bones[30]skeleton.bones[40] 指的是骨骼的手。

BabylonJS - 物理引擎

Babylon.js 具有用於物理引擎的外掛系統,有助於向場景新增互動。它顯示了兩個物件之間的碰撞和反彈,使其更像現實生活中的互動。演示將顯示球體相互碰撞並隨著碰撞四處移動,然後靜止。我們在臺球等遊戲中注意到相同的行為,玩家用球杆擊球,球體與其他球體碰撞等等。在這裡,物理引擎試圖提供球體碰撞和反彈時在撞擊地面時的逼真檢視。該引擎具有類和 API,有助於應用脈衝、力、改變速度、回撥函式,以便在需要時呼叫,以及當我們需要執行某些操作時,如果網格與其他網格碰撞。

可以使用 3 個物理外掛:

  • Cannon.js
  • Oimo.js
  • Energy.js

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Ball/Ground Demo</title>
      <script type = "text/javascript" src="https://cdn.babylonjs.com/Oimo.js"></script>
      <script src = "babylon.js"></script>	
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var v3 = BABYLON.Vector3;
         
         var createScene = function () {	
            // This creates a basic Babylon Scene object (non-mesh)
            var scene = new BABYLON.Scene(engine);

            var camera = new BABYLON.ArcRotateCamera("Camera", 0.86, 1.37, 250, BABYLON.Vector3.Zero(), scene);
            
            camera.attachControl(canvas);
            camera.maxZ = 5000;
            camera.lowerRadiusLimit = 120;
            camera.upperRadiusLimit = 430;
            camera.lowerBetaLimit =0.75;
            camera.upperBetaLimit =1.58 ;

            new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);

            var randomNumber = function (min, max) {
               if (min == max) {
                  return (min);
               }
               var random = Math.random();
               return ((random * (max - min)) + min);
            };

            var mat = new BABYLON.StandardMaterial("ground", scene);
            var t = new BABYLON.Texture("images/gr1.jpg", scene);
            t.uScale = t.vScale = 10;
            mat.diffuseTexture = t;
            mat.specularColor = BABYLON.Color3.Black();
            
            var g = BABYLON.Mesh.CreateBox("ground", 200, scene);
            
            g.position.y = -20;
            g.position.x = 0
            g.scaling.y = 0.01;
            g.material = mat;	
            
            scene.enablePhysics(new BABYLON.Vector3(0, -10, 0), new BABYLON.OimoJSPlugin());
            
            g.physicsImpostor = new BABYLON.PhysicsImpostor(g, BABYLON.PhysicsImpostor.BoxImpostor, { 
               mass: 0, 
               restitution: 0.9 
            }, scene);
            
            var getPosition = function(y) {
               return new v3(randomNumber(-100, 100), y, randomNumber(-100, 100));
            };
            
            var allspheres = [];
            var y = 50;
            var max = 50;
            
            for (var index = 0; index < max; index++) {
               var redSphere = BABYLON.Mesh.CreateSphere("s" + index, 32, 8, scene);
               redSphere.position = getPosition(y);
               redSphere.physicsImpostor = new BABYLON.PhysicsImpostor(redSphere, BABYLON.PhysicsImpostor.SphereImpostor,{
                  mass: 1, restitution:0.9
               }, scene);
               
               redSphere.physicsImpostor.applyImpulse(new BABYLON.Vector3(1, 2, -1), new BABYLON.Vector3(1, 2, 0));
               
               var redMat = new BABYLON.StandardMaterial("ground", scene);
               redMat.diffuseColor = new BABYLON.Color3(0.4, 0.4, 0.4);
               redMat.specularColor = new BABYLON.Color3(0.4, 0.4, 0.4);
               redMat.emissiveColor = BABYLON.Color3.Red();
               redSphere.material = redMat;
               
               // push all spheres in the allspheres variable
               allspheres.push(redSphere);			
               y += 10; // increment height
            }
            scene.registerBeforeRender(function() {
               allspheres.forEach(function(obj) { 
                  // if the sphers falls down its updated again over here
                  // If object falls
                  if (obj.position.y < -100) {
                     obj.position = getPosition(200);				
                  }
               });
            })
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Physics engine

在本演示中,我們使用了影像images/gr1.jpg。這些影像儲存在本地 images/ 資料夾中,並在此下方提供參考。您可以下載任何您選擇的影像,並在演示連結中使用。

images/gr1.jpg

GR1

解釋

scene.enablePhysics(new BABYLON.Vector3(0,-10,0), new BABYLON.OimoJSPlugin());

以上程式碼啟用物理外掛。您可以使用您選擇的外掛。我們使用了 OimoJsplugin()。

g.physicsImpostor = newBABYLON.PhysicsImpostor(g, BABYLON.PhysicsImpostor.BoxImpostor, { 
   mass: 0, 
   restitution: 0.9 
}, scene);

對於互動,物理引擎使用模擬器。當應用於模擬器時,物件的形狀不能更改。如果更改,則必須建立一個新的模擬器。

對於球體,我們將設定模擬器併為其新增脈衝以產生反彈效果,如下所示:

redSphere.physicsImpostor = new BABYLON.PhysicsImpostor(
   redSphere, BABYLON.PhysicsImpostor.SphereImpostor, { 
      mass: 1, 
      restitution:0.9
   }, scene
);

redSphere.physicsImpostor.applyImpulse(
   new BABYLON.Vector3(1, 2, -1), 
   new BABYLON.Vector3(1, 2, 0)
);

物理模擬器引數

考慮以下物理效果引數:

物件

此處物件是您想要應用互動的物件。例如,球體、盒子等。

型別

型別可以是以下之一:

  • BABYLON.PhysicsImpostor.SphereImpostor;
  • BABYLON.PhysicsImpostor.BoxImpostor;
  • BABYLON.PhysicsImpostor.PlaneImpostor;
  • BABYLON.PhysicsImpostor.MeshImpostor;
  • BABYLON.PhysicsImpostor.CylinderImpostor;
  • BABYLON.PhysicsImpostor.ParticleImpostor;
  • BABYLON.PhysicsImpostor.HeightmapImpostor;

質量

唯一必需的引數是質量,它是物件的質量(以千克為單位)。值為 0 將建立一個靜態模擬器 - 適用於地面。

恢復係數

這是物體在碰撞時“回饋”的力的大小。低值將不會產生反彈,而值為 1 將產生非常有彈性的互動。

scene.registerBeforeRender(function() {
   allspheres.forEach(function(obj) { 
      // if the sphers falls down its updated again over here
      // If object falls
      if (obj.position.y < -100) {
         obj.position = getPosition(200);
      }					
   });
})

以上程式碼將落在地面上的球體帶回。它會不斷更新地面上任何落下的球體。在瀏覽器中嘗試以上演示以檢視物理效果。

BabylonJS - 播放聲音和音樂

沒有聲音和音樂,遊戲是不完整的。BabylonJS 聲音引擎帶有一個 API,有助於為遊戲新增聲音效果。當遊戲中出現戰鬥場景時,您需要獲得槍聲,這可以使用 babylonjs 聲音引擎在這裡實現。您可以根據鍵盤/滑鼠控制效果獲得遊戲的聲音效果。聲音引擎提供環境音效、專業音效和定向音效。該引擎支援 .mp3 和 .wav 聲音格式。

語法

var music = new BABYLON.Sound(
   "Music", "sound.wav", scene, null, { 
      loop: true, 
      autoplay: true 
   }
);

引數

考慮以下與聲音引擎相關的引數:

  • 名稱 - 聲音的名稱。

  • URL - 要播放的聲音的 url。

  • 場景 - 要播放聲音的場景。

  • 回撥函式 - 當聲音準備好播放時呼叫的回撥函式。目前為 null。我們將介紹一些示例並學習如何使用它。

  • Json 物件 - 此物件包含需要執行的操作的基本詳細資訊。

  • sound.autoplay - 透過此設定,檔案下載後聲音會自動播放。

  • loop:true - 這意味著聲音將連續迴圈播放。

在您的專案目錄中建立 sound 資料夾,並下載任何樣本音訊檔案以測試輸出。

現在讓我們向我們已經建立的場景新增聲音。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Scene- Playing sounds and music</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>
   
   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);
            
            var music = new BABYLON.Sound("sound", "sounds/scooby.wav", scene, null, { 
               loop: true, 
               autoplay: true 
            });	
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Basic Scene Without Sound

現在讓我們檢查回撥函式是如何工作的。如果您不希望聲音自動播放,或者只想在需要時播放聲音,則可以使用回撥函式。

例如:

Var music = new BABYLON.Sound ("Music", "music.wav", scene, function callback() {music.play();});

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Scene- Playing sounds and music</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true)
            
            var music = new BABYLON.Sound(
               "sound", "sounds/scooby.wav", scene, function callback() { setTimeout(function() {music.play();}, 5000)});	
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

在回撥中,我們將使用 setTimeout。這意味著,我們只想在特定時間後播放聲音。我們添加了 5 秒作為計時器,因此當 Scooby.wav 檔案下載完畢並經過 5 秒後,聲音將播放。

使用點選和鍵盤按鍵播放聲音

單擊場景中的任何位置,您將聽到爆炸聲效;如果您按下任何箭頭鍵(左、右、上或下),它將播放爆炸聲效。

對於點選,我們將事件onmousedown附加到視窗;對於按鍵,我們將使用 keydown 事件。根據按鍵碼播放聲音。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Scene- Playing sounds and music</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true)
            
            var sound = new BABYLON.Sound("gunshot", "sounds/explosion.wav", scene);

            window.addEventListener("mousedown", function (evt) {	
               if (evt.button === 0) { // onclick
                  sound.play();
               }
            });

            window.addEventListener("keydown", function (evt) { // arrow key left right up down
               if (evt.keyCode === 37 || evt.keyCode === 38 || evt.keyCode === 39 || evt.keyCode === 40) {
                  sound.play();
               }
            });		
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行將生成以下輸出:

Basic Scene Without Sound

您可以控制開始時遇到的 json 物件中的聲音音量。

例如:

Var music = new BABYLON.Sound("sound", "sounds/scooby.wav", scene, null, { 
   loop: true, 
   autoplay: true, 
   volume:0.5 
});

要了解聲音檔案何時播放完畢,可以使用以下事件:

music.onended = function () {	
   console.log("sound ended");
   
   //you can do the required stuff here like play it again or play some other sound etc.
};

如果您除了建構函式之外還想控制聲音,也可以使用 SetVolume 屬性。

例如:

music.setVolume(volume);

如果您在場景中播放多個聲音,可以為所有建立的聲音設定一個全域性聲音。

例如:

BABYLON.Engine.audioEngine.setGlobalVolume(0.5);

建立三維空間聲音

如果您想將聲音轉換為空間聲音(類似於空間音效的聲音),需要在聲音建構函式中新增選項。

例如:

var music = new BABYLON.Sound("music", "sounds/explosion.wav", scene, null, { 
   loop: false, 
   autoplay: true, 
   spatialSound: true 
});

以下是空間聲音的不同選項:

  • DistanceModel - 預設情況下使用“線性”方程。其他選項包括“反比”或“指數”。

  • MaxDistance - 設定為 100。這意味著當監聽者距離聲音超過 100 個單位時,音量將為 0。您將聽不到聲音。

  • PanningModel - 設定為“HRTF”。規範說明它是一種使用與人類受試者測量的衝激響應進行卷積的更高質量的空間化演算法。它指的是立體聲輸出。

  • MaxDistance - 僅當 distanceModel 為線性時使用。反比或指數模式下不使用。

空間聲音演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Scene- Playing sounds and music</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);
            
            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);	
            
            var music = new BABYLON.Sound(
               "music", "sounds/explosion.wav", scene, null, {
                  loop: false, autoplay: true, spatialSound: true, distanceModel: "exponential"
               }
            );
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

將聲音附加到網格

使用 BABYLON.Sound,您可以將聲音附加到網格。如果網格在移動,聲音也會隨之移動。AttachtoMesh (mesh) 是要使用的方法。

演示

<!doctype html>
<html>
   <head>
      <meta charset = "utf-8">
      <title>BabylonJs - Basic Scene- Playing sounds and music</title>
      <script src = "babylon.js"></script>
      <style>
         canvas {width: 100%; height: 100%;}
      </style>
   </head>

   <body>
      <canvas id = "renderCanvas"></canvas>
      <script type = "text/javascript">
         var canvas = document.getElementById("renderCanvas");
         var engine = new BABYLON.Engine(canvas, true);
         var createScene  = function() {
            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0, 1, 0);

            var camera = new BABYLON.ArcRotateCamera("Camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, true);

            var materialforbox = new BABYLON.StandardMaterial("texture1", scene);
            var box = BABYLON.Mesh.CreateBox("box", '2', scene);	
            box.material  = materialforbox;
            materialforbox.ambientColor = new BABYLON.Color3(1, 0, 0.2);

            var music = new BABYLON.Sound("music", "sounds/explosion.wav", scene, null, { 
               loop: false, 
               autoplay: true, 
               spatialSound: true, 
               distanceModel: "exponential"
            });	
            music.attachToMesh(box);
            return scene;
         };
         var scene = createScene();
         engine.runRenderLoop(function() {
            scene.render();
         });
      </script>
   </body>
</html>

輸出

以上程式碼行生成以下輸出:

Spatial 3D Sound
廣告