babylon初探

一个简单的场景

首先我们用最少的代码构建一个简单的3D场景,让各位读者对Babylon构建场景的代码复杂度有个初步的认知。

代码采用vue3+ts的方式构建,其中Babylon部分单独使用ts文件抽离出来。

最终效果
ts部分代码(Babylon)
typescript 复制代码
import {
  Engine, // 引擎
  Scene, // 场景
  ArcRotateCamera, // 角旋转相机
  Vector3, // 三维向量
  HemisphericLight, // 方向光
  AxesViewer // 辅助坐标轴
} from "@babylonjs/core";

export default class {
  engine: Engine;

  scene: Scene;

  camera: ArcRotateCamera;

  light: HemisphericLight;

  constructor(canvas: HTMLCanvasElement) {
    // 构建渲染引擎, 传入canvas画布,是否开启抗锯齿
    this.engine = new Engine(canvas, true);
    // 创建一个场景, 传入引擎
    this.scene = new Scene(this.engine);
    // 创建一个相机,设定参数,传入场景
    this.camera = new ArcRotateCamera(
      "camera1", // 相机名称
      0, // 定义相机沿经度轴的旋转角度
      0, // 定义相机沿纬度轴的旋转角度
      10, // 定义相机距离目标点的距离
      Vector3.Zero(), // 定义相机目标点,这里使用0向量,即0,0,0点
      this.scene // 定义相机所属的场景
    );
    /**
     * 为相机启动鼠标控制,第一个参数是为了兼容历史版本保留的,
     * 现在无用,如果要使用第二个参数,第一个参数传入null即可,
     * 第二个参数是是否在鼠标事件触发时不调用preventdefault,
     * 传入true则不调用,默认undefined也就是false。
     */
    this.camera.attachControl(null, false);
    // 设置相机位置
    this.camera.setPosition(new Vector3(50, 40, 15));
    // 定义一个方向光, 传入光源名称,方向向量,所属场景
    this.light = new HemisphericLight(
      "light1",
      new Vector3(3, 2, 1),
      this.scene
    );
    // 给场景加入坐标系辅助,传入所属场景和坐标轴线长度,无需保存到全局变量中
    new AxesViewer(this.scene, 10);
    // 调用渲染函数
    this.run();
  }
  run(){
    // 调用引擎的循环渲染函数,在函数中调用场景的渲染函数
    this.engine.runRenderLoop(() => {
      this.scene.render();
    })
    // 监听窗口变化,调用resize函数
    window.addEventListener('resize', () => {
      this.engine.resize();
    })
  }
}
vue部分(调用ts文件构建场景)
typescript 复制代码
<template>
  <div style="width: 100vw; height: 100vh">
    <canvas ref="canvasRef" style="height: 100%; width: 100%"></canvas>
  </div>
</template>

<script setup lang="ts">
import { Ref, ref, onMounted } from "vue";
import Demo from "./babylonDemo01.ts";

const canvasRef: Ref<HTMLCanvasElement | undefined> = ref();

onMounted(() => {
  new Demo(canvasRef.value!);
});
</script>
<style scoped lang="postcss"></style>

结合代码中的注释,我们还是很容易看懂每一步的意义的。

其中引擎、场景、相机是必不可少的基本要素,缺少任意一个就无法渲染出图像。

引擎
typescript 复制代码
// 构建渲染引擎, 传入canvas画布,是否开启抗锯齿
    this.engine = new Engine(canvas, true);
场景
typescript 复制代码
// 创建一个场景, 传入引擎
    this.scene = new Scene(this.engine);
相机
typescript 复制代码
// 创建一个相机,设定参数,传入场景
    this.camera = new ArcRotateCamera(
      "camera1", // 相机名称
      0, // 定义相机沿经度轴的旋转角度
      0, // 定义相机沿纬度轴的旋转角度
      10, // 定义相机距离目标点的距离
      Vector3.Zero(), // 定义相机目标点,这里使用0向量,即0,0,0点
      this.scene // 定义相机所属的场景
    );

剩余的光线,坐标轴等就不再赘述。

下面我们试着添加一个立方体,以下代码追加到构造函数的尾部。

typescript 复制代码
import {
  Engine,
  Scene,
  ArcRotateCamera,
  Vector3,
  HemisphericLight,
  AxesViewer,  
  MeshBuilder,
  StandardMaterial,
  Color3
} from "@babylonjs/core";
    // 以上是更新后的import
    ...
    this.run();
    // 以上是之前的构造函数
    // 以下是创建立方体的步骤
    // 创建一个立方体,传入尺寸参数和所属场景
    const box = MeshBuilder.CreateBox('box1', {
      height: 5,
      width: 6,
      depth: 7
    }, this.scene);
    // 创建一个材质,传入所属场景
    const material = new StandardMaterial('boxMat', this.scene);
    // 设置材质的漫反射颜色
    material.diffuseColor = Color3.Blue();
    // 将立方体的材质设为上面定义的材质
    box.material = material;
  }
 ...
运行结果
相关推荐
brzhang4 小时前
我操,终于有人把 AI 大佬们 PUA 程序员的套路给讲明白了!
前端·后端·架构
止观止5 小时前
React虚拟DOM的进化之路
前端·react.js·前端框架·reactjs·react
goms5 小时前
前端项目集成lint-staged
前端·vue·lint-staged
谢尔登5 小时前
【React Natve】NetworkError 和 TouchableOpacity 组件
前端·react.js·前端框架
Lin Hsüeh-ch'in5 小时前
如何彻底禁用 Chrome 自动更新
前端·chrome
augenstern4167 小时前
HTML面试题
前端·html
张可7 小时前
一个KMP/CMP项目的组织结构和集成方式
android·前端·kotlin
G等你下课7 小时前
React 路由懒加载入门:提升首屏性能的第一步
前端·react.js·前端框架
蓝婷儿8 小时前
每天一个前端小知识 Day 27 - WebGL / WebGPU 数据可视化引擎设计与实践
前端·信息可视化·webgl
然我8 小时前
面试官:如何判断元素是否出现过?我:三种哈希方法任你选
前端·javascript·算法