Babylonjs基本模板

babylonjs官网:www.babylonjs.com/

无论你是创建一个完整的世界或只是放置一个模型到一个网页,你需要一个 场景包含世界或模型, 相机来观察它, 灯光照亮它,当然,至少有一个可视对象作为模型。所有的模型,无论是一个方块或一个复杂的字符,都是由三角形或面的 网格

HTML模板

xml 复制代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>Babylon Template</title>
        <style>
            html, body {
                overflow: hidden;
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
            }
            #renderCanvas {
                width: 100%;
                height: 100%;
                touch-action: none;
            }
        </style>
        
        <!-- 引入Babylonjs -->
        <script src="https://cdn.babylonjs.com/babylon.js"></script>
    </head>

    <body>
      //画布
      <canvas id="renderCanvas"></canvas>
      <script>
        const canvas = document.getElementById("renderCanvas"); // 获取画布
        const engine = new BABYLON.Engine(canvas, true); // // 创建渲染引擎
        const createScene = function () {
            const scene = new BABYLON.Scene(engine);//创建场景
            
            /*创建一个弧形旋转摄像机
            *"Camera":  摄像机名称
            * 第一个 Math.PI / 2 : alpha, 可理解为水平角度
            * 第二个 Math.PI / 2 : beta, 可理解为垂直角度
            * 2: radius, 半径
            * new BABYLON.Vector3(0, 0, 5)目标点的三维位置,可理解为中心.这是一个向量类的实例
            * scene: scene,场景变量.
            * UniversalCamera通用相机,ArcRotateCamera弧形旋转摄像机,FollowCamera跟随相机,
            * AnaglyphUniversalCamera立体通用相机,AnaglyphArcRotateCamera立体弧形旋转相机等
            */
            const camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new BABYLON.Vector3(0, 0, 5), scene);
            camera.attachControl(canvas, true);//让相机控制画布
            
            /*创建灯光
            * 第一个参数: name. 名字.
            * 第二个参数: direction, 方向,是一个向量的实例.
            * 第三个参数: scene, 场景.
            * HemisphericLight半球形光源,PointLight点光源,DirectionalLight平行光,SpotLight聚光灯
            */
            const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);//创建灯光
            
            /*创建网格
            * 第一个参数 name:  物体名称
            * 第二个参数 options: 参数对象,可以为物体设置长宽,体积等
            * 第三个参数 scene: 加入到的场景
            * CreateBox立方体,CreateSphere球体,CreatePlane平面,CreateGround地面
            */
            const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2, segments: 32}, scene);
            const ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 6, height: 6}, scene);
            
            return scene;
        };
        
        const scene = createScene();
        
        //调用engine的runRenderLoop方案,执行scene.render()渲染场景
        engine.runRenderLoop(function () {
                scene.render();
        });
        
        //监听浏览器改变大小的事件,通过调用engine.resize()来自适应窗口大小
        window.addEventListener("resize", function () {
           engine.resize();
        });
	</script>
   </body>
</html>

可用软件包

vue中使用BabylobJS

安装babylonjs软件包

npm install @babylonjs/core

npm install @babylonjs/gui

...

依次安装即可

vue3模板

1.目录下创建一个名为 scenes的文件夹,在该文件夹中创建babylon场景文件(.js文件)

2.babylon场景文件中的代码

javascript 复制代码
import {
  Engine,
  Scene,
  FreeCamera,
  Vector3,
  MeshBuilder,
  StandardMaterial,
  Color3,
  HemisphericLight,
} from '@babylonjs/core'

const createScene = (canvas) => {
  const engine = new Engine(canvas) //渲染引擎
  const scene = new Scene(engine) //场景

  const camera = new FreeCamera('camera1', new Vector3(0, 5, -10), scene) //相机
  camera.setTarget(Vector3.Zero()) //相机定位到原点
  camera.attachControl(canvas, true) //相机控制画布

  new HemisphericLight('light', Vector3.Up(), scene) //创建半球形光源

  const box = MeshBuilder.CreateBox('box', { size: 2 }, scene) //创建盒子网格

  //设置材质纹理
  const material = new StandardMaterial('box-material', scene)
  material.diffuseColor = Color3.Blue()
  box.material = material

  // 渲染场景
  engine.runRenderLoop(() => {
    scene.render()
  })
}

export { createScene }

3. .vue文件中的代码(我们将构建一个可复用的Vue组件,它可用于显示BabylonJS场景。)

xml 复制代码
<template>
  <canvas ref="bjsCanvas" width="500" height="500" />
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { createScene } from '../../scenes/my-first-scene'
const bjsCanvas = ref(null)
onMounted(() => {
  if (bjsCanvas.value) {
    createScene(bjsCanvas.value)
  }
})
</script>

<style scoped></style>

效果如图:

vue3+ts模板

1.目录下创建一个名为 scenes的文件夹,在该文件夹中创建babylon场景文件(.ts文件)

2.babylon场景文件中的代码

arduino 复制代码
import {
  Engine,
  Scene,
  ArcRotateCamera,
  FreeCamera,
  Vector3,
  MeshBuilder,
  StandardMaterial,
  Color3,
  HemisphericLight,
} from '@babylonjs/core'

//创建一个名为 BabylonScene 的类
export class BabylonScene {
  engine: Engine
  scene: Scene

  //private将属性或方法标记为私有,表示它们只能在类的内部被访问,外部无法直接访问。
  constructor(private canvas: HTMLCanvasElement) {
    this.engine = new Engine(this.canvas, true) //渲染引擎
    this.scene = this.CreateScene() //场景
    // 渲染场景
    this.engine.runRenderLoop(() => {
      this.scene.render()
    })
  }

  CreateScene(): Scene {
    const scene = new Scene(this.engine) // 创建场景
    //创建相机
    const camera = new ArcRotateCamera(
      'camera',
      Math.PI / 8,
      Math.PI / 8,
      10,
      new Vector3(0, 0, 0)
    )
    camera.attachControl(this.canvas, true) //让相机控制画布

    const light = new HemisphericLight('light', new Vector3(0, 1, 0), scene) // 创建半球形光源
    light.intensity = 0.7 // 将灯光调暗

    // 创建球形
    const sphere = MeshBuilder.CreateSphere(
      'sphere',
      { diameter: 2, segments: 32 },
      scene
    )
    // 将球向上移动球高度的1/2
    sphere.position.y = 1
    sphere.position.x = 2

    //创建立方体
    const box = MeshBuilder.CreateBox(
      'box',
      { height: 2, width: 2, depth: 2 },
      scene
    )
    //位移
    box.position.y = 1
    box.position.x = -2

    const myMaterial = new StandardMaterial('material', scene)
    /*设置材质颜色
     *漫反射颜色diffuseColor、镜面颜色specularColor、自发光颜色emissiveColor、环境颜色ambientColor
     */
    // myMaterial.diffuseColor = new Color3(1,0,1)
    myMaterial.diffuseColor = Color3.Red()
    myMaterial.alpha = 0.7
    box.material = myMaterial

    // 内置"地面"形状。
    const ground = MeshBuilder.CreateGround(
      'ground',
      { width: 6, height: 6 },
      scene
    )
    return scene
  }
}

3. .vue文件中的代码

xml 复制代码
<template>
  <canvas ref="bjsCanvas" touch-action="none" width="500" height="500"></canvas>
</template>

<script setup lang="ts">
import { ref, Ref, onMounted } from 'vue'
import { BabylonScene } from '../../scenes/my-first-scene'

const bjsCanvas = ref(null)
onMounted(() => {
  new BabylonScene(bjsCanvas.value!)
})
</script>

<style scoped></style>

效果如图:

导入资产

场景加载器SceneLoader使用前要先引入相应文件的loaders插件,这一步很重要

javascript
xml 复制代码
<script src="https://preview.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
vue
arduino 复制代码
import '@babylonjs/loaders/glTF'
import '@babylonjs/loaders/STL'
import '@babylonjs/loaders/OBJ'

步骤1,3同上

2.babylon场景文件中的代码

javascript 复制代码
import {
  Engine,
  Scene,
  ArcRotateCamera,
  FreeCamera,
  Vector3,
  MeshBuilder,
  StandardMaterial,
  Color3,
  HemisphericLight,
  CubeTexture,
  SceneLoader,
} from '@babylonjs/core'
import '@babylonjs/loaders/glTF'

//创建一个名为 BabylonScene 的类
export class BabylonScene {
  engine: Engine
  scene: Scene

  //private将属性或方法标记为私有,表示它们只能在类的内部被访问,外部无法直接访问。
  constructor(private canvas: HTMLCanvasElement) {
    this.engine = new Engine(this.canvas, true) //渲染引擎
    this.scene = this.CreateScene() //场景
    // 渲染场景
    this.engine.runRenderLoop(() => {
      this.scene.render()
    })
  }

  CreateScene(): Scene {
    const scene = new Scene(this.engine) // 创建场景

    //创建并返回由工具根据预过滤数据创建的纹理
    const hdrTexture = CubeTexture.CreateFromPrefilteredData(
      '/3d/textures/environment.dds',
      scene
    )
    //创建默认天空盒
    const currentSkybox = scene.createDefaultSkybox(
      hdrTexture,
      true,
      undefined,
      0.25,
      true
    )

    //创建相机
    const camera = new ArcRotateCamera(
      'camera',
      Math.PI / 8,
      Math.PI / 8,
      10,
      new Vector3(0, 0, 0)
    )
    camera.attachControl(this.canvas, true) //让相机控制画布

    const light = new HemisphericLight('light', new Vector3(0, 1, 0), scene) // 创建半球形光源
    light.intensity = 0.7 // 将灯光调暗

    /**
     * 一、从文件文件夹中加载所有资源并附加到场景中
     * 配置项:文件夹路径,资源名称,场景对象,回调函数
     */
    // SceneLoader.Append(
    //   '/public/3d/common_assets/',
    //   'WaterBottle.glb',
    //   scene,
    //   function (scene) {}
    // )

    /**
     * 二、从文件中加载所有资源并创建一个新场景
     * 配置项:文件夹路径,资源名称,引擎对象,回调函数
     */
    // SceneLoader.Load(
    //   '/public/3d/common_assets/',
    //   'WaterBottle.glb',
    //   engine,
    //   function (newScene) {}
    // )

    /**
     * 三、从文件中加载网格并将其附加到场景
     * 配置项:将要添加到场景中的模型名称或为空(将所有模型或者骨骼加载),文件夹路径,资源名称,场景对象,回调函数
     */
    // SceneLoader.ImportMesh(
    //   '',
    //   '/public/3d/common_assets/',
    //   'WaterBottle.glb',
    //   scene,
    //   function (scene) {}
    // )

    /**
     * 四、从文件文件夹中加载所有资源但不会自动添加到场景中
     * 回调函数会返回一个容器对象container,里面包含所有模型加载的资源光源,模型,相机等等。
     * 配置项:文件夹路径,资源名称,场景对象,回调函数
     */
    SceneLoader.LoadAssetContainer(
      '/public/3d/common_assets/',
      'WaterBottle.glb',
      scene,
      function (container) {
        //手动加载所有资产到场景中
        container.addAllToScene()
        // //将添加的资产从场景中删除
        // container.removeAllFromScene()
      }
    )

    //五、使用Async函数来实现链式回调
    // SceneLoader.LoadAssetContainerAsync(
    //   '/public/3d/common_assets/',
    //   'WaterBottle.glb',
    //   scene
    // ).then((container) => {
    //   //加载所有资产到场景中
    //   container.addAllToScene()
    //   //将添加的资产从场景中删除
    //   container.removeAllFromScene()
    // })
    return scene
  }
}

效果如图:

相关推荐
Marshall35722 天前
Canvas 和 SVG 的高级使用与性能优化
前端·svg·canvas
webmote4 天前
做一个FabricJS.cc的中文文档网站——面向markdown编程
canvas·fabric·使用手册·中文·fabricjs
小黄人软件11 天前
【AI协作】让所有用电脑的场景都能在ChatGPT里完成。Canvas :新一代可视化交互,让AI易用易得
人工智能·chatgpt·canvas
柳晓黑胡椒14 天前
cesiusm实现 多图例展示+点聚合(base64图标)
css3·canvas·base64·cesium·animation
余生H21 天前
即时可玩web小游戏(二):打砖块(支持移动端版) - 集成InsCode快来阅读并即时体验吧~
前端·javascript·inscode·canvas·h5游戏
普兰店拉马努金1 个月前
【Canvas与图标】牛皮纸文件袋图标
canvas·图标·文件袋·牛皮纸
德育处主任1 个月前
前端啊,拿Lottie炫个动画吧
前端·svg·canvas
GDAL1 个月前
深入剖析Canvas的getBoundingClientRect:精准定位与交互事件实现
canvas
剑亦未配妥1 个月前
使用js和canvas、html实现简单的俄罗斯方块小游戏
前端·javascript·canvas·1024程序员节
howard20051 个月前
2.1 HTML5 - Canvas标签
html5·canvas