全网最详Babylon.js入门教材-第一个3D场景

Q:Babylon.js是什么?🤔️

Babylon.js 是一个强大的、开源的、基于 WebGL 和 WebGPU 的 3D 引擎,用于在网页上创建和渲染 3D 图形。它提供了一套丰富的 API 和功能,包括物理引擎、粒子系统、骨骼动画、碰撞检测、光照和阴影等,可以帮助开发者快速创建复杂的 3D 场景和交互。

Q:我为什么要写该系列的教材? 🤔️

因为公司业务的需要因而要在项目中使用到 Babylon.js,虽然官方的文档看起来覆盖面都挺全,且 playgroud(https://playground.babylonjs.com/) 上的案例也都比较多,但一些具体的 API 或者功能属性也都没有特别多详细的介绍,包括很多使用方式的很多坑都得自己去源码中或者 论坛上(https://forum.babylonjs.com/)找。在将其琢磨完之后, 决定写一系列关于它的教材来帮助更多 babylon.js 的使用者或者是期于学习 Web 3D 的开发者。同时也是自己对其的一种巩固。

Babylon.js第一个3D场景

这一章节主要是介绍 Babylon.js 的基本使用,适合完全没有接触过 babylon.js 的新手或者想要在项目中使用它的开发者。

通过这一章节的讲解你可以学习到:

  • 如何在 html 文件或者前端工程化项目中使用 Babylon.js

  • 两个最简单的 Babylon.js 案例

  • 对案例中各个 API 及名词做解释

  • Babylon.js 和 Three.js 的区别

为了让大家能对 Babylon.js 有一个更直观的感受,可以看一下用它能实现哪些酷炫的功能:

0def5ee1ad96bff70411d6a0b743635a.gif


以上在线浏览地址:https://playground.babylonjs.co‍m/#ARN6TJ#5

7d1f103eb34794e8ee565ed98881c6ca.gif

以上在线浏览地址:https://playground.babylonjs.com/#C21DGD#3

741c11faa2febffe7efd0f39e783ad84.gif


以上在线浏览地址:https://playground.babylonjs.com/#1HH4OJ#29

aa28b5063a2ecd5f035b030e35dc243d.gif

以上在线预览地址:https://yuka.babylonpress.org/examples/js/playground/hideAndSeek/

源码地址:https://github.com/eldinor/yuka-babylonjs-examples/blob/main/examples/js/playground/hideAndSeek/src/World.js

等掌握了一些基础使用后,我也会慢慢地教大家如何实现这些功能。不过眼下,还是让我们先入门吧~ [偷笑]。

.html文件引入Babylon.js引擎

Babylon.js 和大部分开源库一样,要使用时都有 CDN 及 npm 包两种方式来使用。

在 .html 文件中通过 script 标签引入,这里可以使用 Babylonjs 官方的 CDN 地址进行引入:

<script src="https://cdn.babylonjs.com/babylon.js"></script>

请注意:最好不要在生产环境中使用CDN,官方 CDN 的目的是为学习如何使用平台或运行小型实验的用户提供巴比伦包。

通过引入 babylonjs 的 CDN,我们就可以在自己的 js 脚本中通过 BABYLON 来使用 babylon 相关的能力了。

例如:

<script>
 // 通过 BABYLON 来获取 babylon.js 暴露的类
 // BABYLON.Engine
 // BABYLON.Scene
</script>

npm包引入Babylon.js

另一种方式就是通过 npm 下载安装使用 Babylon.js 了:

npm install --save @babylonjs/core

// or
yarn install --save @babylonjs/core

使用:

import * as BABYLON from '@babylonjs/core';

// or
import { Engine, Scene } from '@babylonjs/core';

最简案例

Babylon.js 封装了很多简单好用的API,我们可以使用这些API快速地构建出我们的第一个3D世界。

例如我们可以通过以下代码构建出一个这样的 3D 世界:

e89a16296862b60b56210964f0472006.gif


代码如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Babylon.js Example 01</title>
    <style>
      html,
      body {
        overflow: hidden;
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
      }

      #renderCanvas {
        width: 100%;
        height: 100%;
        touch-action: none;
      }
    </style>
    <script src="https://cdn.babylonjs.com/babylon.js"></script>
  </head>

  <body>
    <canvas id="renderCanvas"></canvas>

    <script>
      // 获取 canvas 元素
      const canvas = document.getElementById('renderCanvas');
      // 初始化 Babylon.js 引擎
      const engine = new BABYLON.Engine(canvas);

      const createScene = function () {
        // 创建一个场景
        const scene = new BABYLON.Scene(engine);
        const box = BABYLON.MeshBuilder.CreateBox('box', {});
        scene.createDefaultCameraOrLight(true, true, true);
        scene.createDefaultEnvironment();

        return scene;
      };
      // 创建场景
      const scene = createScene();
      // 注册一个渲染循环,以便在每一帧都渲染场景
      engine.runRenderLoop(function () {
        scene.render();
      });
      // 监听窗口大小变化,调整引擎的大小
      window.addEventListener('resize', function () {
        engine.resize();
      });
    </script>
  </body>
</html>

(或者可以在此进行在线预览:https://playground.babylonjs.com/#MJNICE)

刨除掉 html、css 那一部分的代码,我们着重看一下 script 标签中的逻辑。

如果你有过 2D Canvas 相关开发经验的话,看到这部分代码应该会觉得很熟悉。3D 和 2D 一样,在浏览器中都是需要有一个 Canvas DOM 元素来充当画布的。

在此,我们通过 document 相关的 API 获取到它,并初始化一个 Babylon.js 的引擎,将 Canvas 传入其中。Engine 就如它的名字一样,是 Babylon.js 中的一个核心组件,它负责管理和处理与 WebGL 或 WebGPU 的底层交互。渲染循环管理、资源管理、画布和视口管理、设备和浏览器兼容性等都是 Engine 的主要功能职责。

接着我们再创建一个 Babylon.js 的场景,即 new BABYLON.Scene(engine) 这行代码。场景(Scene)是一个容器,用于存放和管理所有的3D对象、相机、灯光等元素。通过将模型添加到场景中,模型才能被渲染并显示在屏幕上。如果大家有使用过PPT的话,就不难理解引擎与场景的关系了。引擎就好比是整个PPT项目,而每一页PPT就好比是场景。

然后我们依次的创建了位于场景中心的一个立方体、默认的相机和默认的灯光,以及默认的环境。

之所以你能够正确的看到立方体,就是 scene.createDefaultCameraOrLight(true, true, true); 这行代码发挥了作用。它会帮助我们创建一个弧度旋转相机以及你看到的照射在立方体上的灯光:

278e11421e350e6102af690a158b467a.jpeg


至于 scene.createDefaultEnvironment(); 是帮我们创建一个默认环境。可能在这个案例中你去掉它还是加上它感知不会特别大,实际上它会帮我们增加一个地板以及一个天空盒(如下图所示,把相机拉到很远的位置,可以看到一个方方正正的半透明立方体),这部分我们在后面的学习中也会慢慢提到,现在先不展开。

608456f2f6c98daeb814b06f500f664e.jpeg


最后,也是 Babylon.js 渲染最重要的一步,使用 engine.runRenderLoop 向 engine 中注册一个渲染函数,在这个渲染函数中调用场景的渲染函数。

这里的 engine.runRenderLoop 有点类似于我们浏览器上的 window.requestAnimationCallback,是每帧渲染的时候都会执行的,而在此,我们每帧要做的事就是渲染 scene,这样才能保证我们每时每刻对 scene 上的操作能成功的渲染出来。

第二个案例

上面的第一个案例更多用到的还是 Babaylon.js 提供的一些创建默认元素的 API,那接下来我们来看一个稍微复杂一些些的案例。

以下案例麻雀虽小,五脏俱全,展示了Babylon.js的整套渲染系统:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Babylon.js Example 02</title>
  <style>
    html,
    body {
      overflow: hidden;
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
    }

    #renderCanvas {
      width: 100%;
      height: 100%;
      touch-action: none;
    }
  </style>
  <script src="https://cdn.babylonjs.com/babylon.js"></script>
</head>

<body>
  <canvas id="renderCanvas"></canvas>

  <script>
    // 获取 canvas 元素
    const canvas = document.getElementById("renderCanvas");
    // 初始化 Babylon.js 引擎
    const engine = new BABYLON.Engine(canvas, true);

    const createScene = function () {
      // 创建一个场景
      const scene = new BABYLON.Scene(engine);
      // 创建一个摄像机,并将其放置在场景中
      const camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);
      // 摄像机指向场景的原点
      camera.setTarget(BABYLON.Vector3.Zero());
      // 使摄像机响应鼠标和键盘事件
      camera.attachControl(canvas, true);
      // 创建一个简单的环境光源
      const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
      // 设置光源的强度
      light.intensity = 0.7;
      // 创建一个立方体
      const box = BABYLON.MeshBuilder.CreateBox("box", { size: 1 }, scene);
      // 将立方体移动到场景的 (0, 1, 0) 位置
      box.position.y = 1;
      // 创建一个材质,并将其应用到球体上
      const material = new BABYLON.StandardMaterial("material", scene);
      material.diffuseColor = new BABYLON.Color3(0, 1, 0);
      box.material = material;

      return scene;
    };
    // 创建场景
    const scene = createScene();
    // 注册一个渲染循环,以便在每一帧都渲染场景
    engine.runRenderLoop(function () {
      scene.render();
    });
    // 监听窗口大小变化,调整引擎的大小
    window.addEventListener("resize", function () {
      engine.resize();
    });
  </script>
</body>

</html>

d7740943db26decc8b2c063c4de07a1e.jpeg


各API及名词解释

虽然案例二中的代码都有一些注释,但是针对一些API和名词我们还是再来看看它们的细节部分。

立方体Box

const box = BABYLON.MeshBuilder.CreateBox("box", { size: 1 }, scene);

MeshBuilder 是 babylonjs 暴露的一个工具,用于创建各种形状的3D模型,而 CreateBox 是 MeshBuilder 的一个方法,专门用于创建盒子形状的模型。

CreateBox 方法接受三个参数:

  • 第一个参数是模型的名称,在这个例子中是 "box"。这个名称是唯一的标识符,可以用来在后续的代码中引用这个模型。

  • 第二个参数是一个对象,用于定义盒子的属性。在这个例子中,只设置了一个属性 size,其值为 1。这意味着创建的盒子在所有三个维度(宽度、高度和深度)上的大小都是1个单位。

  • 第三个参数是 scene,它是创建这个盒子模型所在的场景的引用。也就是这个 box 应该被添加到哪个场景中。

第二个参数其实还有一些其他的属性,例如可以直接通过 width、height、deep 三个属性来设置 box 的长宽高。

const box = BABYLON.MeshBuilder.CreateBox("box", { size: 1 }, scene);

// 等同于
onst box = BABYLON.MeshBuilder.CreateBox("box", { width: 1, height: 1, deep: 1 }, scene);

刚刚提到了 MeshBuilder 可以用于创建各种形状的3D模型,那么除了 CreateBox,还有:

  • 球形:CreateSphere

  • 圆柱:CreateCylinder

  • 胶囊:CreateCapsule

  • 面板:CreatePlane

  • 圆环:CreateTorus

  • 文本:CreateText

  • ......

官网地址传送门:https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/set

更多的功能,我们也会在第二章 Babylon.js中插入几何体 详细介绍。

材质Material

const material = new BABYLON.StandardMaterial("material", scene);
material.diffuseColor = new BABYLON.Color3(0, 1, 0);
box.material = material;

代码 const material = new BABYLON.StandardMaterial("material", scene); 创建了一个新的标准材质。BABYLON.StandardMaterial 是BABYLON.js中用于创建材质的一个类,它提供了多种可以调整的属性来改变物体的外观。在这个例子中,我们创建了一个名为 "material" 的新材质,并将其与之前定义的场景 scene 关联。每个材质都需要一个唯一的名称和一个场景作为参数。

接下来,material.diffuseColor = new BABYLON.Color3(0, 1, 0); 这行代码设置了材质的漫反射颜色。漫反射颜色是物体表面在多方向上反射光线的颜色,这通常是物体的主要颜色。

其中的 BABYLON.Color3 是一个用于定义颜色的类,接受三个参数:红色、绿色和蓝色的值,范围从 0 到 1。在这个例子中,颜色被设置为纯绿色,因为红色和蓝色的值为 0,而绿色的值为 1,所以最终我们看到的立方体也就是绿色了。

创建完了材质后,还需要通过 box.material = material; 这行代码将创建的材质应用到之前创建的盒子模型上。通过将 material 属性设置为我们创建的材质,盒子模型就会使用这个材质的外观设置进行渲染。

更多的功能,我们也会在第三章 Babylon.js中设置材质效果之标准材质 详细介绍。

相机Camera

// 创建一个摄像机,并将其放置在场景中
const camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);
// 摄像机指向场景的原点
camera.setTarget(BABYLON.Vector3.Zero());
// 使摄像机响应鼠标和键盘事件
camera.attachControl(canvas, true);

这段代码展示了如何在BABYLON.js中创建和配置一个自由摄像机(FreeCamera),以及如何使其响应用户输入。

const camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene); 这行代码创建了一个自由摄像机。

BABYLON.FreeCamera 是BABYLON.js中用于创建自由摄像机的类。自由摄像机允许用户自由移动和旋转摄像机,以从不同的角度查看场景。这个摄像机被命名为 "camera1",并被放置在坐标 (0, 5, -10) 的位置,这意味着它位于场景原点正前方的上方和稍微后方的位置。

其次通过 camera.setTarget(BABYLON.Vector3.Zero()); 设置摄像机的目标点为场景的原点。在 BABYLON.js 中有很多便捷的方法,例如 BABYLON.Vector3.Zero() 返回一个所有坐标值为0的向量,即场景的几何中心。这样设置后,摄像机将会朝向并围绕场景的中心点旋转,使得用户可以围绕场景的中心查看模型和对象。

至于 camera.attachControl(canvas, true); 这行代码使摄像机能够响应用户的鼠标和键盘输入。这里的 canvas 是渲染3D场景的HTML画布元素的引用。第二个参数 true 表示在用户与摄像机交互时,画布将捕获并不再传播鼠标事件,这有助于避免滚动页面或触发其他不相关的事件。

相机交互指的是:你可以按住鼠标左键在场景中来回移动,或者点击键盘前后,来操控相机。

可以试试如果把 camera.attachControl(canvas, true); 注释掉,鼠标键盘交互事件就不能响应了。

灯光(Light)

// 创建一个简单的环境光源
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
// 设置光源的强度
light.intensity = 0.7;

new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene); 创建了一个环境光源。

  • 第一个参数是光源的名称

  • 第二个参数是光源的方向(在这个例子中,光源是从上到下照射的)

  • 第三个参数是光源所在的场景

light.intensity = 0.7; 设置了光源的强度。强度越高,光源提供的光照效果就越强烈。在上面这个例子中,光源的强度被设置为 0.7,这意味着光源提供的光照效果是中等强度的。你可以试着设置不同的值,例如调小,来观察立体几何的明暗。调小了立体几何也变暗了,这也很好理解,现实生活中灯光强度变低了,周围的景物自然也会暗淡。Babylon.js 对WebGL光照模型算法都进行了封装,不需要你了解计算机图形学, 可以直接使用调用Babylon.js光源相关API直接创建一个光源对象,就像你使用普通的三维建模渲染软件一样,只是这里多了一个Javascript编程语言而已。

和相机、材质等一样,灯光也有很多的类型,例如聚光灯、点光源、平行光等,这部分内容会在灯光那一章节再详细讲解。

整个程序的结构

9dd0f161ade16ae462b46de61456ed51.png

其他Babylon.js相关的package

在文章的开头,教大家引用了 @babylonjs/core 这个包,但官方其实还提供了很多其他的包。

  • @babylonjs/materials - Babylon 支持的高级材料的集合。

  • @babylonjs/loaders - Babylon 的所有官方加载器(OBJ、STL、glTF)。

  • @babylonjs/后处理 - Babylon 的后处理。

  • @babylonjs/procedural-textures - 官方支持的程序纹理。

  • @babylonjs/serializers - 场景/网格序列化器。

  • @babylonjs/gui - Babylon.js GUI 模块。

  • @babylonjs/查看器 - 独立的 Babylon.js 查看器。

  • @babylonjs/检查器 - 用于可视化调试的 Babylon.js 检查器。

  • @babylonjs/ktx2decoder - Babylon 的 KTX2 Decoder 模块。

CDN的话也有对应的地址:

<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/babylon.max.js"></script>

<script src="https://cdn.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
<script src="https://cdn.babylonjs.com/materialsLibrary/babylonjs.materials.js"></script>

<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.js"></script>

<script src="https://cdn.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
<script src="https://cdn.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.js"></script>

<script src="https://cdn.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
<script src="https://cdn.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.js"></script>

<script src="https://cdn.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
<script src="https://cdn.babylonjs.com/serializers/babylonjs.serializers.js"></script>

<script src="https://cdn.babylonjs.com/gui/babylon.gui.min.js"></script>
<script src="https://cdn.babylonjs.com/gui/babylon.gui.js"></script>

<script src="https://cdn.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
<script src="https://cdn.babylonjs.com/inspector/babylon.inspector.bundle.max.js"></script>

<script src="https://cdn.babylonjs.com/viewer/babylon.viewer.js"></script>
<script src="https://cdn.babylonjs.com/viewer/babylon.viewer.max.js"></script>

Babylon.js和Three.js的区别

Three.js可以被归类为一个3D图形库,它提供了一系列用于在Web浏览器中创建和渲染3D图形的API和功能。它是基于WebGL技术的封装,简化了使用WebGL的复杂性,使开发者能够更轻松地创建和展示3D场景。

虽然Three.js提供了许多功能和工具,但它并不是一个完整的渲染引擎。渲染引擎通常提供更高级的功能,如场景管理、光照计算、阴影生成等。而Three.js更多地关注于提供基础的3D图形渲染功能和工具,如几何体创建、材质和纹理应用、相机控制、动画效果等。

因此,可以说Three.js是一个3D图形库,它提供了一些渲染引擎所需的功能,但并不是一个完整的渲染引擎。它可以作为一个框架来使用,帮助开发者构建和展示复杂的3D场景,同时也可以与其他库和工具结合使用,以满足更高级的需求。

Babylon.js可以被归类为一个完整的3D渲染引擎。它是一个基于WebGL技术的开源框架,提供了全面的功能和工具,用于创建和渲染复杂的3D场景。

与Three.js相比,Babylon.js更加注重提供完整的3D渲染引擎功能。它提供了丰富的特性,包括场景管理、光照计算、阴影生成、碰撞检测、粒子系统、动画控制等。Babylon.js还提供了一些高级功能,如物理引擎集成、虚拟现实(VR)和增强现实(AR)支持等。

除了基础的3D渲染功能,Babylon.js还提供了一些辅助工具和库,如材质库、纹理库、模型导入和导出工具等,以帮助开发者更高效地创建和管理3D场景。

因此,可以说Babylon.js是一个完整的3D渲染引擎,它提供了广泛的功能和工具,使开发者能够构建复杂的3D场景,并具备一些框架的特性,可以用于开发各种类型的3D应用程序。

其他的话,Three.js 是一个独立的开源项目,没有大公司直接支持,但个人认为 Three.js 的社区和使用人群更多[苦笑~],因为网上大部分都是 Three.js 的文章。不过 Babylon.js 由微软支持,在企业级应用中更受青睐。

其他 Babylon.js 学习资料推荐

官方文档:https://doc.babylonjs.com/

论坛(疑难杂症可在此查询):https://forum.babylonjs.com/

大佬翻译的 Babylon.js 中文教程:https://doc.cnbabylon.com/

后语

知识无价,支持原创!这篇文章就介绍到这里。

喜欢霖呆呆的小伙伴还希望可以关注霖呆呆的公众号 LinDaiDai

我会不定时的更新一些前端方面的知识内容以及自己的原创文章🎉。

你的鼓励就是我持续创作的主要动力 😊。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值