BABYLON 三维开发工具的使用

✍️ 作者简介: 最近在摸鱼。

🧣 微博: GuoJ阝阝(fu)

BABYLON三维工具



前言

  • 最近忙着开发一款手机端的导购工具,大概的功能就是根据客户的厨房户型,快速生成一个三维场景,模拟装修后的效果,让客户有个直观的概念。
  • 这个软件主要用的就是vue框架,vant组件,还有就是开发三维场景的babaylon.js。
  • 这篇文章拖了很久都没更新,原因是Babylon真的是不容易精通,而且我也没有花费很大精力在这上面。最近工作不多,时不时的更新一下

一、babylon.js是什么?

  • 我觉得搜到这篇文章的人都知道babylon.js是什么,那肯定是为了构建三维场景用到的js框架。
  • 随便写一下:Babylon.js是一款WebGL开发框架,是微软推动的,功能强大,开源。

二、使用步骤

1.引入文件

代码如下(示例):

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="./static/babylon/cannon.js"></script>
    <script src="https://preview.babylonjs.com/babylon.js"></script>
    <script src="./static/babylon/babylonjs.loaders.js"></script>
    <script src="./static/babylon/babylonjs.serializers.js"></script>
    <script src="./static/babylon/babylon.gui.min.js"></script>
    <script src="./static/babylon/babylon.inspector.bundle.js"></script>
    <script src="./static/babylon/dat.gui.min.js"></script>

这些文件我都直接放到项目中了,通过html引入。这么做是担心以后babylon.js更新版本会影响到我的项目。这些文件可以按需引入,各有各的功能。具体下载地址我就不写了,随便一搜就有。

2.渲染一个场景

代码如下:

<template>
	<div class="layout-result-inner" id="renderCanvasWrapper">
		// 自定义加载中的显示
		<div id="loadingScreen"></div>
		// 主场景
		<canvas id="renderCanvas"></canvas>
	</div>
</template>

methods: {
	// 创建Babylon场景
	initBabylon() {
		// 注意Babylon相关的变量最好存储在window对象里,千万别用vue的双重绑定变量存储,那样会非常卡
		window.canvas = document.getElementById("renderCanvas");
		// 设置cavas的尺寸
	    var renderCanvasWrapper = document.getElementById("renderCanvasWrapper");
	    window.canvas.height = renderCanvasWrapper.clientHeight;
	    window.canvas.width = renderCanvasWrapper.clientWidth;
	    // 创建babylon引擎
	    window.engine = new window.BABYLON.Engine(window.canvas, true);
	    window.engine.doNotHandleContextLost = true;
	    // 显示自定义的加载界面
	    let loadingScreenDiv = window.document.getElementById("loadingScreen");
	    function CustomLoadingScreen() {}
	    // 模型的loading页,显示加载进度信息
	    CustomLoadingScreen.prototype.displayLoadingUI = function () {
	      loadingScreenDiv.innerHTML = "正在加载...";
	    };
	    CustomLoadingScreen.prototype.hideLoadingUI = function () {
	      loadingScreenDiv.style.display = "none";
	    };
	    var loadingScreen = new CustomLoadingScreen();
	    window.engine.loadingScreen = loadingScreen;
	    window.engine.displayLoadingUI();

		// 创建场景
      	window.scene = this.createScene(window.engine);
      	window.engine.runRenderLoop(function () {
	        window.scene.render();
	    });
	    // 监听屏幕的变化
	    window.addEventListener("resize", function () {
	        window.engine.resize();
	    });
	    // 所有物体可操作化
      	this.handlePickAlive()
	},
	// 创建场景和相机
    createScene(engine) {
	  // 设置像素的精确度,数值越小越清晰,但是帧数下降厉害
      engine.setHardwareScalingLevel(1);
      // 创景场景
      var scene = new window.BABYLON.Scene(engine);
      // 初始化相机的设置
      this.initCamera(scene, engine, this.cameraOrbit, window.canvas);
      // 初始化环境灯光
      this.initLight(scene, engine)
      // 初始化场景中的实体
      this.initMeshes(scene)
      // 性能优化
      let containerAll = new BABYLON.AssetContainer(scene);
      containerAll.removeAllFromScene();
      containerAll.addAllToScene();

      // 添加虚拟摇杆
      const baseWidth = document.getElementsByClassName("bottom-last-step")[0].clientWidth - 30
      const topOffset = document.getElementsByClassName("bottom-last-step")[0].offsetHeight
      // 获取屏幕中心点位置,设置摇杆
      const leftOffset = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) / 2
      this.leftThumbContainer(window.camera, scene, canvas, topOffset, leftOffset, baseWidth);
    },
    // 初始化相机
    initCamera(scene, engine, cameraOrbit, canvas) {
		// 漫游视角照相机
	    window.camera = new window.BABYLON.FreeCamera(
	      "freeCamera",
	      new window.BABYLON.Vector3(vue.cameraY * 1, vue.cameraZ * 1, vue.cameraX * 1),
	      scene
	    );
	    window.camera.invertRotation = true; // 相机反转
	    window.camera.inverseRotationSpeed = 3; // 相机转动速度
	    if (typeof vue.rotation !== "undefined")
	      window.camera.rotation.y = (vue.rotation * Math.PI) / 180;
	    // 设置camera的属性 
	    window.camera.inputs.addMouseWheel(); // 添加滚轮输入
	    window.camera.inputs.attached.mouse.touchEnabled = true;
	    window.camera.speed = 100; // 移动速度
	    window.camera.angularSensibility = 1300
	    window.camera.minZ = 10; // 渲染距离范围 太小会闪面
	    window.camera.maxZ = 20000;
	    window.camera.fov = 1.6; // 广角
	    window.camera.inertia = 0.8
	    // 设置相机每个窗口的大小
	    window.camera.viewport = new BABYLON.Viewport(0, 0, 1, 1);
	    window.camera.attachControl(canvas, true);
	    // 将漫游视角相机设置为激活状态
	    scene.activeCameras.push(window.camera);
	    scene.activeCamera = window.camera;
	    scene.cameraToUseForPointers = window.camera;
	},
	// 初始化环境光照
	initLight(scene, engine) {
		// 从下往上照射的半球光
	    var lightUP = new BABYLON.HemisphericLight("hemiLight", new BABYLON.Vector3(0, -1, 0), scene);
	    lightUP.intensity = 0.28;
	    // 模拟环境光的半球光
	    var lightEnv = new BABYLON.HemisphericLight("hemiLight", new BABYLON.Vector3(0, 1, 0), scene);
	    lightEnv.intensity = 0.8; // 曝光度
	    lightEnv.diffuse = new BABYLON.Color3(1, 1, 1); // 漫反射
	    lightEnv.specular = new BABYLON.Color3(1, 1, 1); // 镜面反射
	    lightEnv.groundColor = new BABYLON.Color3(0.8, 0.8, 0.8); // 地面颜色
	    // 启用物理引擎
	    var gravityVector = new window.BABYLON.Vector3(0, -98, 0);
	    var physicsPlugin = new window.BABYLON.CannonJSPlugin();
	    scene.enablePhysics(gravityVector, physicsPlugin);
	    // 设置重力,与场景相同
	    scene.gravity = new window.BABYLON.Vector3(0, -9.81, 0);
	    window.camera.applyGravity = true;
	    // 可以碰撞
	    scene.collisionsEnabled = true;
	    window.camera.checkCollisions = true;
	    // Set the player size, the camera's ellipsoid.
	    window.camera.ellipsoid = new window.BABYLON.Vector3(350, 1.2 * 500, 250);
	    window.camera.position.y = 1.2 * 1000; // 相机初始高度
	    // 初始化地面
	    var ground = window.BABYLON.MeshBuilder.CreateGround(
	    "ground",
	    { height: 30000, width: 30000, subdivisions: 4 },
	    scene
	    );
	    ground.checkCollisions = true;
	    ground.isVisible = false;
	    ground.freezeWorldMatrix();
	
	    window.gizmoManager = new BABYLON.GizmoManager(scene);
	    window.gizmoManager.usePointerToAttachGizmos = false;
	    // 环境光
	    scene.environmentTexture =
	    window.BABYLON.CubeTexture.CreateFromPrefilteredData(
	    "../textures/xiequ_yuan_8k.env",
	    scene
	    );
	    scene.environmentIntensity = 1; // 环境光强度
	    scene.imageProcessingConfiguration.contrast = 1; // 对比度
	    scene.imageProcessingConfiguration.exposure = 0.8; // 曝光度
		// 天空盒
	    let skybox = window.BABYLON.Mesh.CreateBox("skyBox", 2000.0, scene);
	    let skyboxMaterial = new window.BABYLON.StandardMaterial("skyBox", scene);
	    skyboxMaterial.backFaceCulling = false;
	    skyboxMaterial.reflectionTexture = new window.BABYLON.CubeTexture("../textures/skybox/city/city", scene);
	    skyboxMaterial.reflectionTexture.coordinatesMode = window.BABYLON.Texture.SKYBOX_MODE;
	    skyboxMaterial.diffuseColor = new window.BABYLON.Color3(0, 0, 0);
	    skyboxMaterial.specularColor = new window.BABYLON.Color3(0, 0, 0);
	    skyboxMaterial.disableLighting = true;
	    skybox.material = skyboxMaterial;
	    skybox.material.disableDepthWrite = true;
	    skybox.infiniteDistance = true;
	    skybox.isPickable = false;
	},
	// 初始化场景中的物体
	initMeshes(scene) {
		var path = "";
	    let modelName = "";
	    // 根据地址和文件名加载gltf文件
		window.BABYLON.SceneLoader.ImportMesh("", path, modelName, scene, function (meshes) {
        // 模型加载完成,隐藏自定义加载界面
        engine.hideLoadingUI();
        this.autoRoamingAnim = window.autoRoamingAnim;
        let containerTmp = new BABYLON.AssetContainer(scene);
        scene.registerBeforeRender(function () {
          if (window.camera.position.z < 400) {
            containerTmp.addAllToScene();
          } else {
            containerTmp.removeAllFromScene();
          }
        });
      },
      function (event) {
        // onProgress
        if (event.lengthComputable) {
          let loadingScreenDiv = window.document.getElementById("loadingScreen");
          if (eventTotal === 0) {
            eventTotal = event.total;
            loadingScreenDiv.innerHTML = "正在解析模型描述文件...";
          }
          if (event.total !== eventTotal) {
            loadingScreenDiv.innerHTML =
              "开始下载资源...<br />已下载" +
              Math.floor((100 * event.loaded) / event.total) +
              "%";
          }
        }
      }
	}
}

加载Babylon场景的代码太多,看都看烦了,真是懒得再往后写呀。。。


总结

提示:这里对文章进行总结:

最近实在太忙了,后续会慢慢补充的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Babylon.js 是一个基于 WebGL 技术的 3D 游戏引擎,能够在 Web 浏览器中创建和渲染高品质的 3D 场景。以下是使用 Babylon.js 的基本步骤: 1. 引入 Babylon.js 库文件。您可以从 Babylon.js 的官方网站下载最新版本的库文件,将其引入您的 HTML 文件中。 ```html <script src="https://cdn.babylonjs.com/babylon.js"></script> <script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script> ``` 2. 创建场景和相机。使用 `BABYLON.Scene` 类创建一个场景对象,并使用 `BABYLON.FreeCamera` 或 `BABYLON.ArcRotateCamera` 类创建一个相机对象。 ```javascript var canvas = document.getElementById("renderCanvas"); var engine = new BABYLON.Engine(canvas, true); var scene = new BABYLON.Scene(engine); var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true); ``` 3. 加载模型。使用 `BABYLON.SceneLoader` 类从文件中加载 3D 模型,并将其添加到场景中。 ```javascript BABYLON.SceneLoader.ImportMesh("", "models/", "myModel.babylon", scene, function (newMeshes) { // 可以在此处对模型进行处理 // ... }); ``` 4. 创建光源。使用 `BABYLON.Light` 类创建一个光源对象,并将其添加到场景中。 ```javascript var light = new BABYLON.PointLight("pointLight", new BABYLON.Vector3(0, 10, 0), scene); ``` 5. 渲染场景。使用 `BABYLON.Engine` 类的 `runRenderLoop` 方法渲染场景。 ```javascript engine.runRenderLoop(function () { scene.render(); }); ``` 这只是 Babylon.js 的一些基本用法,您可以参考官方文档了解更多功能和用法。Babylon.js 的官方文档地址为:https://doc.babylonjs.com/ 。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值