BabylonJS - 快速指南

BabylonJS - 简介

Babylon.js 是一个 javascript 开源框架,用于开发网络 3D 应用程序/视频游戏。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 是使用 TypScript 开发的,因此它既强大又安全。

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
转到 cd BabylonJS/
npm install

所需的文件将在 BabylonJS 文件夹中提供。

您可以使用 VSCode (Microsoft Visual Studio Code) 进行编辑。代码带有内置功能,如突出显示任何错误、突出显示语法等。您可以使用您选择的编辑器,并且不强制只使用 VSCode。

BabylonJS - 概述

BabylonJS 是一个开源 Javascript 框架,用于使用 HTML5 和 WEBGL 构建 3D 游戏。它托管在 github 上。BabylonJS 的官方网站是 www.babylonjs.com。

在 3D 动画世界中,形状是用三角形绘制的。使用 WebGL,复杂性会随着过程中涉及的大量编码而增加。BabylonJS 是一种简单的解决方案,可以减轻增加的复杂性。在这里,灯光、相机、引擎的 API 很容易处理,并且可以创建 3D 对象。

babylonJS 的源代码是用 typescript 编码的。它被编译为 Javascript 并提供给最终用户。

要开始使用 Babylonjs,请下载 babylonjs 文件,将其托管在您的终端,然后您就可以开始编写 3D 代码了。

BabylonJS 由微软员工于 2016 年开发。微软窗口和设备组首席项目经理 David Catuhe 是开发 BabylonJs 并使其取得巨大成功的主要人物。

要运行 BabylonJS,我们需要支持 WEBGL 的现代浏览器。最新的浏览器,即 Internet Explorer 11+、Firefox 4+、Google Chrome 9+、Opera 15+ 等,都支持 WEBGL,可以在这些浏览器上执行演示以查看输出。

BabylonJs 提供以下功能,可帮助创建不同类型的 3D 场景 −

  • 形状,如盒子、球体、圆柱体、圆锥体、高地
  • 相机、灯光
  • 网格、纹理、材质
  • 精灵
  • 变形
  • 网格交叉和碰撞检测
  • 物理引擎插件
  • 动作管理器
  • 固体粒子
  • 实例和粒子
  • 支持骨骼和骨架
  • 向场景添加音乐和声音

除了自己的网格之外,BabylonJS 还允许使用由第三方 3D 软件(如 Blender、FBX 和 3DS Max)创建的网格。

Blender

Blender 是一款开源 3D 计算机图形软件产品,用于创建动画场景、3D 打印模型、视频游戏等。Blender 提供 .bablyon 文件,可与 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 基本元素

要运行 BabylonJS,我们需要支持 WEBGL 的现代浏览器。最新的浏览器 -Internet Explorer 11+、Firefox 4+、Google Chrome 9+、Opera 15+ 等确实支持 WEBGL,并且可以在相同的平台上执行演示以查看输出。创建一个目录来存储 babylonjs 的文件。从 BabylonJS 网站获取最新的 BabylonJSscripts 文件。本教程中的所有演示链接均使用 babylonjs 3.3 版测试。

步骤 1

  • 创建一个简单的 html 页面并包含 Babylon.js 文件。

  • 在 body 标签内创建一个用于通过 BabylonJS 呈现内容的 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 步

现在让我们开始使用 BabylonJScode 在画布上渲染内容。

<!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);

在浏览器中执行上述演示链接现在不会在浏览器屏幕上显示任何内容。代码中还有一个步骤需要添加,即步骤 4 中的 engine.runRenderLoop。

步骤 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 并在浏览器中检查输出。显示的屏幕为粉红色,如下所示 −

粉红色输出浏览器屏幕

步骤 5

现在我们有了场景,我们必须向其中添加摄像头。

添加摄像头和灯光

下面给出的代码将摄像头添加到场景中。Babylon 上可以使用多种类型的摄像头。

ArcRotateCamera 是围绕目标旋转的摄像头。它可以通过鼠标、光标或触摸事件进行控制。所需的参数是名称、alpha、beta、半径、目标和场景。让我们在后续部分讨论相机的细节。

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);

现在让我们详细讨论每个形状。

以下是所有形状和语法的摘要 −

Sr.No 形状 语法
1 Box
var box = BABYLON.Mesh.CreateBox(
   "box", 6.0, scene, false, BABYLON.Mesh.DEFAULTSIDE);
2 Sphere
var sphere = BABYLON.Mesh.CreateSphere(
   "sphere", 10.0, 10.0, scene, 
   false, BABYLON.Mesh.DEFAULTSIDE);
3 Plane
var plane = BABYLON.Mesh.CreatePlane(
   "plane", 10.0, scene, false, BABYLON.Mesh.DEFAULTSIDE);
4 Disc
var disc = BABYLON.Mesh.CreateDisc(
   "disc", 5, 30, scene, false, BABYLON.Mesh.DEFAULTSIDE);
5 Cylinder
var cylinder = BABYLON.Mesh.CreateCylinder(
   "cylinder", 3, 3, 3, 6, 1, scene, false, 
   BABYLON.Mesh.DEFAULTSIDE);
6 Torus
var torus = BABYLON.Mesh.CreateTorus(
   "torus", 5, 1, 10, scene, false, 
   BABYLON.Mesh.DEFAULTSIDE);
7 Knot
var knot = BABYLON.Mesh.CreateTorusKnot(
   "knot", 2, 0.5, 128, 64, 2, 3, scene, false, 
   BABYLON.Mesh.DEFAULTSIDE);
8 Line Mesh
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 Dashes Lines
var dashedlines = BABYLON.Mesh.CreateDashedLines(
   "dashedLines", [v1, v2, ... vn], 
   dashSize, gapSize, dashNb, scene);
10 Ribbon
var ribbon = BABYLON.Mesh.CreateRibbon(
   "ribbon", 
   [path1, path2, ..., pathn], 
   false, false, 0, 
   scene, false, 
   BABYLON.Mesh.DEFAULTSIDE);
11 Tube
var tube = BABYLON.Mesh.CreateTube(
   "tube", 
   [V1, V2, ..., Vn], 
   radius, tesselation, 
   radiusFunction, 
   cap, scene, false, 
   BABYLON.Mesh.DEFAULTSIDE);
12 Ground
var ground = BABYLON.Mesh.CreateGround(
   "ground", 6, 6, 2, scene);
13 Ground From HeightMap
var ground = BABYLON.Mesh.CreateGroundFromHeightMap(
   "ground", "heightmap.jpg", 200, 200, 250, 0, 10, 
   scene, false, successCallback);
14 Tiled Ground
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);

基本元素 - 位置、旋转和缩放

在本节中,我们将学习如何定位、旋转或缩放我们迄今为止添加的元素。

我们已经创建了盒子、球体、圆柱体、结等。现在,我们将了解如何定位、缩放和旋转形状。

Sr.No. 元素 &描述
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 的父级,而 boxc 也由于其父级 boxb 而缩放,并且其缩放程度相同。您可以试用演示来了解父子链接的工作原理。

要创建网格,您必须使用另一个网格的父级 −

  • child.parent = parentmesh;

基本元素 - 环境

现在让我们在本节中讨论场景环境。我们将讨论场景中的场景背景颜色、环境颜色、天空盒、雾模式等。

我们已经看到了场景背景颜色是迄今为止我们创建的演示

场景背景颜色

现在让我们看看场景背景颜色是如何工作的。

语法

以下是场景背景颜色的语法 −

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

上述属性将更改场景的背景颜色。

场景环境色

现在让我们看看场景环境色是如何工作的。

语法

以下是场景环境色的语法 −

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

AmbientColor 与 StandardMaterial 环境色和纹理一起使用。如果场景没有 ambientColor,则 StandardMaterial.ambientColorStandardMaterial.ambientTexture 不起作用。一旦应用了场景的 ambientColor,StandardMaterial ambientColor/ambientTexture 将变为活动状态。默认情况下,场景被赋予 scene.ambientColor 并设置为 Color3 (0, 0, 0),这意味着没有 ambientColor。

场景雾模式

现在我们将了解场景雾模式的工作原理。

语法

以下是场景雾模式的语法。

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;

如果雾模式为线性,那么您可以定义雾的开始和结束位置,如下所示 −

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 轴,并在 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

基本元素 Skybox-nx

skybox_ny

基本元素 Skybox-nx

skybox_nz

基本元素 Skybox-nx

skybox_px

基本元素 Skybox-nx

skybox_py

基本元素 Skybox-nx

skybox_pz

基本元素 Skybox-nx

BabylonJS - 材料

材料就像物体的衣服。您可以添加颜色、纹理并用它包裹您的网格。您可以使用相同的材​​料覆盖许多网格。​​网格可以是我们在上一章的例子中看到的场景 - 穿过天空的飞机。

在本章中,我们将学习如何为本章中的网格添加颜色、纹理和反射。

我们将向已经创建的场景添加材料。我们将通过向我们创建的所有形状添加材料来取得进展。

让我们考虑几个例子来了解添加材料的工作原理。

语法

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

上述材料不会改变任何东西,因为它是默认材料。我们将使用可用的属性使对象看起来更具吸引力。

可用的属性如下 −

看看这些应用于材质的属性如何改变网格的外观和感觉。

基本材质属性 - FresnelParameters

Fresnel 是 BabylonJS 在 standardmaterial 上添加的新功能。它允许更改应用于形状的颜色。您可以使用简单的 Fresnel 获得类似玻璃的反射。Fresnel 可让您在边缘上获得更多反射,而不是全部在中心。

Fresnel 有以下属性

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

Demo

<!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>

输出

上述代码行生成以下输出 −

基本材质属性 - 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);

            // 包含所有动画关键点的数组
            var keys = [];
            
            //在动画关键点 0 处,缩放的值为"1"
            keys.push({
            frame: 0,
            value: 1
            });
            
            //在动画关键点 20 处,缩放的值为"0.2"
            keys.push({
            frame: 20,
            value: 0.2
            });
            
            keys.push({
            frame: 60,
            value: 0.4
            });
            
            //在动画关键点 100 处,缩放的值为"1"
            keys.push({
            frame: 100,
            value: 1
            });
            
            animationBox.setKeys(keys);
            box.animations = [];
            box.animations.push(animationBox);
            scene.beginAnimation(box, 0, 100, true);
            
            // 包含所有动画关键点的数组
            var keys = [];
            
            //在动画关键点 0 处,缩放的值为"1"
            keys.push({
            frame: 0,
            value: 1
            });
            
            //在动画关键点 20 处,缩放的值为"0.2"
            keys.push({
            frame: 60,
            value: 0.2
            });
            
            //在动画关键点 100 处,缩放的值为"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

// 包含所有动画关键点的数组
var keys = [];

//在动画关键点 0 处,缩放的值为"1"
keys.push({
frame: 0,
value: 1
});

//在动画关键点 20 处,缩放的值为"0.2"
keys.push({
frame: 20,
value: 0.2
});

//在动画关键点 100 处,缩放的值为"1"
keys.push({
frame: 100,
value: 1
});

animationBox.setKeys(keys);

box.animations = [];

box.animations.push(animationBox);

scene.beginAnimation(box, 0, 100, true); //定义目标形状框的开始和结束。

以下是动画对象 − 上可用的其他函数

  • 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 个关键帧 - startend

演示

<!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>

输出

动画演示图像

动画混合

您可以借助 enableBlending = true; 实现动画混合

此混合动画将从当前对象状态更改。

缓动函数

为了使动画更加令人印象深刻,我们之前已经在 css 中使用了一些缓动函数。

以下是缓动函数列表 −

  • BABYLON.CircleEase ()

  • BABYLON.BackEase (振幅)

  • BABYLON.BounceEase (反弹,弹性)

  • BABYLON.CubicEase ()

  • BABYLON.ElasticEase (振荡,弹性)

  • BABYLON.ExponentialEase (指数)

  • BABYLON.PowerEase (幂)

  • 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);

            // 包含所有动画关键点的数组
            var keys = [];
            
            //在动画关键点 0 处,缩放的值为"1"
            keys.push({
            frame: 0,
            value: 1
            });
            
            //在动画关键点 20 处,缩放的值为"0.2"
            keys.push({
            frame: 60,
            value: 0.2
            });
            
            //在动画关键点 100 处,缩放的值为"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>

输出

动画混合

动画事件

您可以在动画事件上执行任何必要的操作。如果您想在帧更改或动画完成时更改任何内容,可以通过向动画添加事件来实现。

var event1 = new BABYLON.AnimationEvent(50, function() { console.log("Yeah!"); }, true);
//当使用动画将帧更改为 50 时,您将获得 console.log。

animation.addEvent(event1); //将事件附加到动画。

BabylonJS - Sprites

Sprites 在计算机图形学中指的是什么?它基本上是一个集成到较大场景中的二维位图。当将多个较小的图像组合成单个位图以节省内存时,生成的图像称为精灵表。让我们开始使用精灵以及如何使用它们。

开始使用精灵的第一步是创建精灵管理器。

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

考虑以下参数来创建精灵管理器 −

  • 名称 − 此管理器的名称。

  • URL −要使用的图像 URL。

  • 管理器的容量 − 此管理器中的最大实例数。例如,上述实例将创建 2000 棵树。

  • 单元格大小 − 图像占用的大小。

  • scene − 将添加管理器的场景。

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;

Demo

<!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/ 文件夹中,也粘贴在下面以供参考。您可以下载任何您选择的图像并在演示链接中使用。

Tree 使用的图像如下所示。

images/tree.png

BabylonJS Sprites

images/tree1.png

BabylonJS Sprites

images/bird.png

BabylonJS Sprites

现在让我们再看一个带有 sprites-balloons 的演示。

带有 sprites-balloons 的演示

<!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);

在 registerBeforeRender 中调用 animate 函数,该函数负责将气球从初始的 -35 移动到 +3。它通过以 0.05 为增量缓慢移动。

BabylonJS - 粒子

粒子系统是计算机图形学中的一种技术,它利用大量非常小的精灵、3D 模型或其他图形对象来模拟某些类型的"模糊"现象,而这些现象很难用传统的渲染技术再现。

要创建粒子系统,您必须按如下方式调用该类 −

vararticleSystem = new BABYLON.ParticleSystem("particles", 2000, scene);//2000 指的是要产生的粒子总数。

粒子系统需要考虑以下属性 −

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);
            
            // 在动画关键点 0 处,缩放的值为"1"
            keys.push({
            frame: 0,
            value: 0
            });
            
            // 在动画关键点 50 处,缩放的值为"0.2"
            keys.push({
            frame: 50,
            value: Math.PI
            });
            
            // 在动画关键点 100 处,缩放的值为"1"
            keys.push({
            frame: 100,
            value: 0
            });
            
            // 启动动画
            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);

            // 在动画关键点 0 处,缩放的值为"1"
            keys.push({
            frame: 0,
            value: 0
            });
            
            // 在动画关键点 50 处,缩放的值为"0.2"
            keys.push({
            frame: 50,
            value: Math.PI
            });
            
            // 在动画关键点 100 处,缩放的值为"1"
            keys.push({
            frame: 100,
            value: 0
            });
            
            // 启动动画
            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>

输出

演示粒子

带动画的演示

<!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);
            
            // 在动画关键点 0 处,缩放的值为"1"
            keys.push({
            frame: 0,
            value: 0
            });
            
            // 在动画关键点 50 处,缩放的值为"0.2"
            keys.push({
            frame: 50,
            value: Math.PI
            });
            
            // 在动画关键点 100 处,缩放的值为"1"
            keys.push({
            frame: 100,
            value: 0
            });
            
            // 启动动画
                        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 中使用相机。

FreeCamera

现在让我们看看 FreeCamera 的工作原理。

语法

以下是 FreeCamera 的语法 −

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

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

改变方向将改变方向。您可以更改值并查看相机在场景中的行为。

以下是 FreeCamera 使用的参数 −

  • 名称
  • 位置
  • 场景

ArcRotateCamera

此相机围绕给定的目标枢轴旋转。它可以通过光标和鼠标或触摸事件进行控制。参数包括名称、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;

TouchCamera

触摸是一种"手势"。它可以在平板或屏幕上,用手指、触控笔、手套、脚或激光笔。任何可以感知到的动作……都可以被视为手势。

语法

以下是 TouchCamera 的语法 −

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

GamepadCamera

此相机专为与游戏手柄配合使用而设计。

语法

以下是游戏手柄相机的语法 −

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

DeviceOrientationCamera

此相机专门设计用于对设备方向事件做出反应,例如当您向前或向后、向左或向右倾斜设备时等。

语法

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

FollowCamera

FollowCamera 旨在跟随任何具有位置的场景项目。它可以从后方、前方或任何角度跟随。

语法

以下是 FollowCamera 的语法 −

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

VirtualJoysticksCamera

此相机旨在对虚拟操纵杆事件做出反应。虚拟操纵杆是屏幕上的 2D 图形,用于控制相机或其他场景项目。

语法

以下是 VirtualJoysticksCamera 的语法 −

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

AnaglyphCamera

AnaglyphCamera 适用于红色和青色 3D 眼镜。它使用后处理过滤技术。

AnaglyphArcRotateCamera

以下是 AnaglyphArcRotateCamera 的语法 −

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

AnaglyphFreeCamera

以下是 AnaglyphFreeCamera 的语法 −

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

VRDeviceOrientationFreeCamera

VRDeviceOrientationFreeCamera 使用 FreeCamera 作为基础,因此 FreeCamera 的属性和方法也可以在我们的 VRDeviceOrientationFreeCamera 上找到。

语法

以下是 VRDeviceOrientationFreeCamera 的语法 −

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

WebVRFreeCamera

WebVRFreeCamera 使用 FreeCamera 作为基础,因此 FreeCamera 的属性和方法也可以在我们的 WebVRFreeCamera 上找到。

语法

以下是 WebVRFreeCamera 的语法 −

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

在大多数演示中,您会看到 attachControl 将相机附加到画布上。

示例

camera.attachControl(canvas, true);

BabylonJS - 灯光

在本章中,我们将了解 BabylonJS 使用的灯光。我们首先会了解 babylonjs 提供的不同类型的灯光。

灯光用于产生每个像素接收到的漫反射和镜面反射颜色。之后,它会在材质上使用它来获取每个像素的最终颜色。

babylonjs 提供 4 种类型的灯光。

  • 点光源
  • 定向光源
  • 聚光灯
  • 半球光源

BabylonJS - 点光源

点光源的一个典型示例是太阳,其光线会向各个方向散布。点光源在空间中有一个独特的点,它会从那里向各个方向散布光线。可以使用镜面反射和漫反射属性来控制光的颜色。

语法

以下是 Point Light − 的语法

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);

点光源有 5 个不同的参数 −

  • 第 1 个参数是光源的名称。
  • 第 2 个参数是位置。
  • 第 3 个参数是方向。
  • 第 4 个参数是角度。
  • 第 5 个参数是指数。

这些值定义了从位置开始向方向发射的光锥。镜面反射和漫反射用于控制光的颜色。

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 - 参数化形状

参数化形状是指使用弯曲、扭曲等绘制的线条可以实现的不同形状。它是用数学方程生成的 2D 形式,如抛物线、正弦曲线、余弦曲线、贝塞尔曲线等。通过方程,我们可以找到坐标 (x, y) 并为其绘制线条。我们将在本章中看到诸如丝带、线条、虚线、管状、挤压等形状。可以使用下面描述的参数化形状在板上自由手绘线条。

Sr.No. 参数化形状 &描述
1 丝带

丝带以路径数组作为输入,并沿着这些路径绘制线条。它使用复杂的逻辑来获取坐标。在下面给出的示例中,我们使用贝塞尔曲线方程来绘制丝带。贝塞尔曲线主要用于 3D 游戏中,以模拟平滑曲线。曲线需要控制点,曲线沿着控制点绘制。

2 线

线是 3D 游戏中的基本元素。要画一条线,您需要两个可以在其间画线的点。

3

管是一种弯曲的圆柱形状。它可以根据应用于它的方程式(数学函数)给出不同的参数形状以获得坐标。

4 挤压

挤压有助于将 2D 形状转换为体积形状。假设您想用 2D 创建一个星形,您将拥有 x、y 坐标,z 将为 0。采用 2D 坐标挤压会将其转换为 3D 形状。因此,挤压后的 2D 开始将变成 3D。您可以尝试不同的 2D 形状并将它们转换为 3D。

BabylonJS - Mesh

在本章中,我们将学习使用网格生成器创建不同的形状。我们已经在之前的章节中学习了如何创建形状。

不同之处在于,使用网格生成器可以灵活地为形状添加颜色和图像。

使用 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 个精灵,即水平列,如图像中所示

var vSpriteNb = 2; // 如上图所示,有 2 个精灵原始图像。

var faceUV = new Array(6); // 立方体有 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
};

这称为使用 createBox 方法将纹理应用于 meshbuilder。我们使用了图像 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 是纹理裁剪开始位置左下角点的 2D 坐标。Utop、Vtop 是纹理裁剪结束位置右上角点。

var hSpriteNb = 3; // 每个原始图像 3 个精灵
var vSpriteNb = 2; // 2 个精灵原始图像

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);
}

假设默认纹理,即给定的图像应用于盒子的所有面。如果您只想更改盒子的 1 个面或 1 个侧面,您可以直接分配如下所示的值 −

var hSpriteNb = 3; // 每个原始数据 3 个精灵
var vSpriteNb = 2; // 2 个精灵原始数据

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);

使用 mesh 和 meshbuilder 的 CreateCylinder 之间的区别是 - 您可以在 meshbuilder 中使用选项。现在我们使用高度、直径和镶嵌作为传递给圆柱体的选项。我们使用带线框的标准材质作为此网格的材质。检查浏览器中的输出并查看圆柱体。您可以在游戏中使用类似的结构作为场景中旋转的轮子。

演示

<!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>

输出

上述代码生成以下输出 −

网格交点

说明

使用上述代码,我们创建了一个线框为 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 在此处指的是圆柱体网格。

如果球体与圆柱体相交,则球体的颜色变为红色;否则为绿色。

以下代码用于与点相交 −

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 – MeshPicking Collision

Picking Collision 实际上为您提供了坐标,您可以将网格定位在该位置。对象由鼠标拾取,您只需用鼠标单击即可放置。假设您需要将网格(对象)放置在用户单击鼠标的位置;因此,借助 Picking Collision,它可以帮助您获得单击位置的坐标。

演示

<!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);

            //当指针向下事件发生时

            scene.onPointerDown = function (evt, pickResult) {
               // 如果点击击中地面物体,我们会改变撞击位置
               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

说明

在上面的例子中,我们使用了一个平面和两个球体。要生成此输出,请使用以下代码 −

scene.onPointerDown = function (evt, pickResult) {
   // 如果点击击中地面物体,我们会改变撞击位置
   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 坐标,如上所示。一旦位置改变,球体就会放置在您单击和放置鼠标的位置。您可以尝试上述演示。

BabylonJS – 射线投射

射线投射就像太阳光线,用于检查场景中的碰撞和相交。

语法

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

参数

考虑以下射线投射参数 −

  • origin − 射线开始的位置。

  • direction − 射线方向的计算方法如下 −

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;

            //射线显示方向
            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

解释

带有谓词函数的 Raycast 有助于选择我们想要的网格。如果我们不想选择某个网格,我们可以忽略它。

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);

参数

考虑以下与网格阴影相关的参数 −

  • 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

说明

要创建阴影,您需要创建阴影生成器。请考虑以下示例。

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

要定义需要阴影的网格,您需要将其添加到上述生成器中。

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

现在,我们已经创建了一个地面和其上的一个盒子。我们希望盒子的阴影落在地面上。为此,我们需要确保地面被标记为接收阴影,如下所示 −

ground01.receiveShadows = true;

有一些可用于阴影的过滤器,如下所示 −

shadowGenerator.usePoissonSampling = true; - 称为泊松采样
shadowGenerator.useExponentialShadowMap = true; - 指数阴影图
shadowGenerator.useBlurExponentialShadowMap= true; - 模糊指数阴影图

在我们的演示中,我们使用了 shadowGenerator00.useBlurExponentialShadowMap = true;您可以尝试其他方法,看看输出结果如何。

在这里,我们使用了名为 gr1.jpg 的图像。图像存储在本地的 images/ 文件夹中。您可以下载您选择的任何图像并在演示链接中使用。

BabylonJS – 网格上的高级纹理

在本节中,我们将了解网格上的高级纹理。不同的纹理如下所示 −

让我们将一些复杂的纹理应用于网格 - 镜像、凹凸、视频和折射。

Sr.No. 网格 &描述
1 网格高亮层

高亮层用于高亮场景中的网格。您可以为其赋予颜色,并将颜色应用于网格的边框。如果您在游戏中想要高亮,可以使用网格高亮层来实现这一点。

2 网格变形

变形通过某种过渡方式将一个对象的形状更改为另一个对象的形状。我们已经看到了形状的可更新参数;否则,该参数设置为 false。对于变形,将其设置为 true,并更新网格以更改形状。

3 网格操作

操作用于向网格添加交互。单击网格时,或网格相交或碰撞时,会激活事件。

4 网格 AssetsManager

使用assestsmanager 类,您可以在场景中加载网格、图像和二进制文件。

5 导入网格

我们将学习使用导入网格。

6 网格变形目标

我们已经看到了线条、丝带、多边形等的变形。现在,我们将在此演示中看到球体和盒子的变形。使用变形目标,球体的形状会发生变化,如下面的演示所示。

7 网格实例

如果您想要在场景中绘制相同的网格,并利用实例。

8 网格 LOD 和实例

LOD 代表距离线。此功能允许您根据查看者的距离指定网格。随着查看者与物体之间的距离增加,网格的细节级别将通过 LOD 清晰显示。

9 网格 VolumemetricLightScatteringPost-process

此过程会散射光线,如下面的输出所示。在浏览器中测试相同内容,您将看到光线如何散射穿过网格。

10 网格边缘渲染器

EdgesRendering 用于在网格周围绘制边缘,如上面的输出所示。

11 网格混合模式

您可以通过修改材质的 alphamode 来创建混合模式。

12 网格固体粒子

固体粒子系统在网格上更新。我们在网格上看到的所有属性都可以在固体粒子上使用。

13 网格刻面数据

刻面数据占用大量内存,默认情况下不启用此功能。要启用它,我们需要根据需要创建一个网格并向其更新刻面数据。

BabylonJS - VectorPosition 和 Rotation

在浏览器中运行下面给出的演示链接。在下面给出的演示中,我们绘制了 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);

            // 相机
            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);
            
            // 灯光
            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; 
            
            // 材料
            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 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);

            // 相机
            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);
            
            // 灯光
            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; 
            
            // 材料
            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;
            };
            
            // 显示轴
            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 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); // 盒子中心点 x 轴为 -5,y 轴为 3。
            
            var box = BABYLON.Mesh.CreateBox("box", '2', scene);
            box.position = new BABYLON.Vector3(0,3,-3); // 盒子中心点 x 轴为 -5,y 轴为 3。
            
            var redSphere = BABYLON.Mesh.CreateSphere("red", 32, 1, scene); //球体没有位置,因此默认为 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);

            // 相机
            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);
            
            // 灯光
            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; 
            
            // 材料
            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;
            };
            
            // 显示轴
            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);

            // 相机
            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);
            
            // 灯光
            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; 
            
            // 材料
            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;
            };
            // 显示轴
            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 - 贴花

贴花就像粘贴在物体上的贴纸。贴纸绘制是借助绘制在网格(例如游戏中的物体)上的 2d 图像完成的。在游戏中,假设有一支军队在射击子弹,需要在物体上看到子弹的痕迹。因此在 Babylonjs 中,它是使用贴花来完成的,当您单击任何对象时,您将在单击的位置绘制 2D 图像。

贴花用于在创建的网格上添加细节 - 子弹、孔等细节。在下面给出的演示链接中,我们使用图像并将其添加到导入的网格中。

要添加贴花,您可以使用以下代码 −

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]; / /这是屏幕上显示的网格。

   // 将相机的目标设置为第一个导入的网格
   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;
      }

      // 检查我们是否在网格下方
      var pickInfo = scene.pick(scene.pointerX, scene.pointerY, function (mesh) { return mesh === cat;
      // 这将提供所有网格,但它将选择与 cat 相同的网格,如果找到则返回 true });
      if (pickInfo.hit) { // if true
         var decalSize = new BABYLON.Vector3(5, 5, 5); //定义贴花的尺寸

         var newDecal = BABYLON.Mesh.CreateDecal("decal", cat, pickInfo.pickedPoint, pickInfo.getNormal(true), decalSize); //decal is created 
         newDecal.material = decalMaterial; //已添加贴花材质。
      }
   }
   var canvas = engine.getRenderingCanvas();
   canvas.addEventListener("pointerdown", onPointerDown, false);

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

Demo

<!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.HemisphericLight("Hemi", new BABYLON.Vector3(0, 1, 0), scene);

            //添加弧形旋转相机
            var camera = new BABYLON.ArcRotateCamera("Camera", -1.85, 1.2, 200, BABYLON.Vector3.Zero(), scene);

            camera.attachControl(canvas, true);

            // 第一个参数可用于指定要导入哪个网格。这里我们导入所有网格
            BABYLON.SceneLoader.ImportMesh("Shcroendiger'scat", "scenes/", "SSAOcat.babylon", scene, function (newMeshes) {
               var cat = newMeshes[0];

               // 将相机的目标设置为第一个导入的网格
               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中一样。

解释的曲线如下 −

  • 二次贝塞尔曲线
  • 三次贝塞尔曲线
  • Hermite 样条线
  • 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)

参数

考虑以下与三次贝塞尔曲线相关的参数。

  • Origin − 原点。

  • control1 − 矢量形式的第一个控制点。

  • control2 −向量形式的第二个控制点。

  • 目的地 − 向量形式的目的地点。

  • no_of_points − 数组形式的点数。

HermiteSpline 曲线

在本节中,我们将了解 Hermite 样条曲线。

语法

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

参数

考虑与 Hermite 样条曲线相关的以下参数 −

  • p1 − 曲线的原点。

  • t1 − 原点切向量点。

  • p2 − 目标点。

  • t2 − 目标切向量。

  • NbPoints −最终曲线的点数组。

Catmull-Rom 样条曲线

在本节中,我们将了解 Catmull-Rom 样条曲线。

语法

var nbPoints = 20; // 每个 Vector3 控制点之间的点数
var points = [vec1, vec2, ..., vecN]; // 曲线必须经过的 Vector3 数组:控制点
var catmullRom = BABYLON.Curve3.CreateCatmullRomSpline(points, nbPoints);

参数

考虑以下与 Catmull-Rom 样条曲线相关的参数 −

  • Points − Vector3 数组,曲线必须经过控制点。

  • NbPoints − 每个 Vector3 控制点之间的点数。

var path = catmullRom.getPoints(); // getPoints() 返回连续 Vector3 数组。
var l = catmullRom.length(); // 方法返回曲线长度。

Demo

<!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(5, 3, 0), scene);
            camera.setPosition(new BABYLON.Vector3(0, 0, -100));
            camera.attachControl(canvas, true);
            
            // 灯光
            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; 
            
            // 材料
            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;
            };
            
            // 显示轴
            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);

参数

以下是创建动态纹理 − 所需的参数

  • name −动态纹理的名称

  • option − 将具有动态纹理的宽度和高度

  • scene − 创建的场景

语法

以下是在纹理上写入文本的语法 −

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

参数

以下是在纹理上写入文本所需的参数 −

  • text − 要写入的文本;

  • x −距左侧边缘的距离;

  • Y − 距顶部或底部边缘的距离,取决于 invertY;

  • font − 字体定义,格式为 font-style、font-size、font_name;

  • invertY − 默认为 true,此时 y 是距顶部的距离,为 false 时,y 是距底部的距离,字母反转;

  • update − 默认为 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); 

            //创建动态纹理		
            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;

            //将文本添加到动态纹理中
            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>

输出

动态纹理

动态纹理还允许使用 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);

            //创建动态纹理
            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>

输出

动态纹理1

说明

我们已经创建了地面网格并为其添加了动态纹理。

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

//创建动态纹理
var TextureGround = new BABYLON.DynamicTexture("dynamic Texture", 512, scene);

//使用标准材质向地面添加动态纹理
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; − 应用缩放因子,使深度与网格一致。对于视差,介于 .05 和 .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() {
            // 这将创建一个基本的 Babylon Scene 对象(非网格)
            var scene = new BABYLON.Scene(engine);

            // 这将创建并定位一个自由相机(非网格)
            var camera = new BABYLON.ArcRotateCamera("camera1", 0, Math.PI / 2, 100, new BABYLON.Vector3(0, 0, 0), scene);
            camera.attachControl(canvas, false);
            
            // 这将使相机瞄准场景原点
            camera.setTarget(BABYLON.Vector3.Zero());
            
            // 这将创建一个光源,瞄准 0,1,0 - 天空(非网格)
            var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
            
            // 默认强度为 1。让我们将光线调暗一点
            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);

参数

考虑以下参数来创建镜头眩光 −

  • Name −为镜头眩光系统指定的名称。

  • Light − 可以是光源或相机。

  • scene − 将添加镜头眩光的场景。

要向场景添加眩光,请执行以下命令 −

var flare1 = new BABYLON.LensFlare(0.5, 0.15, new BABYLON.Color3(1, 1, 1), "images/sun1.png", lensFlareSystem);
  • 大小 − 0 到 1 之间的浮动值。

  • 位置 −镜头光晕的源(发射器)(可以是相机、灯光或网格)。

  • Lensflaresystem − 使用 lensflaresystem 类创建的对象。

演示

<!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

戒指图片

Images/d1.png

D1 图片

Images/diamond.jpg

钻石图片

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>

输出

反射探针

在此演示中,我们使用了图像 square.jpg。图像存储在本地的 images/ 文件夹中,也粘贴在下面以供参考。您可以下载您选择的任何图像并在演示链接中使用。

images/square.jpg

square

BabylonJS - 标准渲染管道

StandardRenderingPipeline 提供了一组与现实世界相关的后期处理效果。有不同的后期处理效果,例如灯光效果和照明效果。

在下面给出的示例中,您将看到各种效果,如镜头效果、灯光的后期处理效果等。

它使用 HDR 立方体纹理,纹理必须是 .hdr。此纹理提供全景效果,旋转相机时可以看到。

var hdrTexture = new BABYLON.HDRCubeTexture("images/GravelPlaza_REF.hdr", scene, 512);

使用以下代码行调用标准渲染管道类来获得效果 −

// 创建渲染管道
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);

参数

考虑与着色器材质相关的以下参数 −

  • name − 一个字符串,命名着色器。

  • scene −着色器将要使用的场景。

  • Route − 以三种方式之一路由到着色器代码 −

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 一起使用。

  • Options − 对象包含属性和 uniforms 数组,其中包含其名称作为字符串。

带有值的着色器语法如下所示 −

var shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, {
   vertex: "custom",
   fragment: "custom",
},
{
   attributes: ["position", "normal", "uv"],
   uniforms: ["world", "worldView", "worldViewProjection", "view", "projection"]
});

属性必须为数组形式。这些属性包含 position、normal 和 uv,它们是 vector3 3D 浮点向量。

  • 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"] = "
" + 
               "precision highp float;
" + 
               "// Attributes
" + 
               "attribute vec3 position;
" + 
               "attribute vec2 uv;
" + 
               "// Uniforms
" + 
               "uniform mat4 worldViewProjection;
" + 

               "// Varying
" + 
               "varying vec2 vUV;
" + 
               "void main(void) {
                  
" + 
                  "gl_Position = worldViewProjection * vec4(position, 1.0);
" + 
                  "vUV = uv;
"+"
               }
               
";
               BABYLON.Effect.ShadersStore["customFragmentShader"] = "
"+
                  "precision highp float;
" + 
                  "varying vec2 vUV;
" + 
                  "uniform sampler2D textureSampler;
" + 
               "void main(void) {
                  
"+
                  "gl_FragColor = texture2D(textureSampler, vUV);
"+"
               }
               
";

            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);

            //添加光源
            var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(20, 20, 100), scene);

            //添加弧形旋转相机
            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

将文件保存在场景中以获取如下所示的输出。

输出

上面的代码行生成以下输出 −

Skeletons And Bones

说明

对于导入网格,我们使用了 babylonjs dude 网格。

网格为我们提供了骨架。例如,skeleton = Skeletons[0];

要从骨架中获取骨骼,请执行以下命令 −

skeleton.bones; //它给出一个数组。

在上面的演示中,我们创建了 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 () {	
            // 这将创建一个基本的 Babylon Scene 对象(非网格)
            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;
               
               // 将所有球体推送到 allspheres 变量中
               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>

输出

上述代码行生成以下输出 −

物理引擎

在此演示中,我们使用了图像 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)
);

physicsImposter 的参数

考虑以下物理效果参数 −

对象

此处的对象是您想要应用交互的对象。例如,球体、盒子等。

类型

类型可以是以下之一 −

  • 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 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。

  • 场景 − 必须播放声音的场景。

  • 回调函数 − 当声音准备好播放时调用的回调函数。目前,它是空的。我们将通过几个例子来学习如何使用它。

  • Json 对象 − 此对象包含需要执行的操作的基本详细信息。

  • sound.autoplay −这样,文件下载后,声音就会自动播放。

  • loop:true − 这意味着声音将循环播放。

在项目目录中创建声音文件夹,并下载任何示例音频文件以测试输出。

现在让我们将声音添加到我们已经创建的场景中。

演示

<!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 Sc​​ene Without Sound

现在让我们检查一下 callback 函数的工作原理。如果您不希望声音自动播放,或者只想在需要时播放声音,则可以使用回调函数来实现。

例如,

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 Sc​​ene 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("soundended");

//您可以在此处执行所需的操作,例如再次播放或播放其他声音等。
};

如果您想要除了构造函数之外控制声音,也可以使用 SetVolume 属性。

例如,

music.setVolume(volume);

如果您在场景中播放多个声音,则可以为所有创建的声音设置全局声音。

例如,

BABYLON.Engine.audioEngine.setGlobalVolume(0.5);

创建空间 3D 声音

如果您想将声音转换为空间声音(类似于空间声音的声音),则需要向声音构造函数添加选项。

例如,

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