vue3 + Babylon.js 实现3D场景

<script setup>import { ref, getCurrentInstance, onMounted, beforeUnmount } from 'vue'import * as BABYLON from '@babylonjs/core/Legacy/legacy' // 全部引入import '@babylonjs/loaders' // 模型加载loaderimport * as GUI from '@babylonjs/gui/2D' // 交互组件const { proxy } = getCurrentInstance()const emit = defineEmits(['customChange'])let engine = ref(null)let scene = ref(null)let camera = ref(null)// 模型加载进度百分比let progress = ref(0)// 是否完成模型渲染let isRendering = ref(false)// 是否展示视频let showVideo = ref(false)// 自适应渲染const engineResize = ()=> {engine.resize();}// 重置模型const reset = ()=> {scene.activeCamera.restoreState();}onMounted(() => {let canvas = document.getElementById('canvas');// 初始化 BABYLON 3D engineengine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true, disableWebGL2Support: false });// 自定义loading加载效果function customLoadingScreen() {console.log('customLoadingScreen creation');}customLoadingScreen.prototype.displayLoadingUI = function() {console.log('customLoadingScreen loading')};customLoadingScreen.prototype.hideLoadingUI = function() {window.document.getElementById('loadingScreen').style.display = 'none';};engine.loadingScreen = new customLoadingScreen();// 初始化一个场景 scenescene = new BABYLON.Scene(engine);// 设置背景色透明scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);// 初始化相机 cameracamera = new BABYLON.ArcRotateCamera('Camera', 0, 0, 0, new BABYLON.Vector3(0, 0, 0), scene);/** 天空盒*/// 创建天空盒const skybox = BABYLON.Mesh.CreateBox('skyBox', 21000, scene),skyboxMaterial = new BABYLON.StandardMaterial('skyboxMaterial', scene);// 关闭掉材质的背面剔除(在盒子内部也可以看到盒子)skyboxMaterial.backFaceCulling = false;// 删除盒子上的反射光(天空不会反射太阳)skyboxMaterial.disableLighting = true;// 载入天空贴图(CubeTexture是贴图加载器,只能被应用到reflectionTexture)skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture('textures/sky', scene);// 修改贴图模式(reflectionTexture是反射贴图,但我们需要天空盒贴图)skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;skybox.material = skyboxMaterial;// 设置天空盒跟随相机位置移动(盒子不会收缩)skybox.infiniteDistance = true;/** 3D模型*/// 引入外部obj模型BABYLON.SceneLoader.Append('babylon/1/', 'model.glb', scene, (object) => {// 设置默认相机和灯光scene.createDefaultCameraOrLight(true, true, true);const light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(1, 1, 1));// 设置灯光亮度light.intensity = 1;// 镜面反射 漫反射 环境光颜色调整light.diffuse = new BABYLON.Color3(1, 1, 1);light.specular = new BABYLON.Color3(1, 1, 1);// 渲染模型后调整相机角度、位置、观察对象的三维坐标scene.activeCamera.alpha = 0.0239;scene.activeCamera.beta = 1.51;scene.activeCamera.radius = 51.9;scene.activeCamera.setPosition(new BABYLON.Vector3(51.85, 4.32, 4.45));scene.activeCamera.setTarget(new BABYLON.Vector3(0.04, 1.4, 3.2));// 设置横向旋转角度上下限scene.activeCamera.upperBetaLimit = Math.PI * 0.5;scene.activeCamera.lowerBetaLimit = 0;// 设置镜头到目标位置距离半径的最大值scene.activeCamera.upperRadiusLimit = 102;// 设置鼠标滚轮灵敏度(数值越小灵敏度越高)scene.activeCamera.wheelPrecision = 10;// 控制鼠标平移相机镜头灵敏度(数值越小灵敏度越高|为0的时候取消平移操作)scene.activeCamera.panningSensibility = 200;// 存储当前相机状态scene.activeCamera.storeState();// 关闭自定义loading效果、展示标题、展示按钮setTimeout(() => {engine.hideLoadingUI();emit('showTitle', true);isRendering = true;});}, (progressEvent) => {// 设置模型加载进度百分比progress = (progressEvent.loaded / progressEvent.total).toFixed(0) * 100;});// 注册渲染循环 runRenderLoopengine.runRenderLoop(() => {scene.render();});// 在 DOM 更新后执行回调nextTick(() => {console.log('DOM 已更新');// 注册resize监听事件window.addEventListener('resize', engineResize);});})beforeUnmount(() => {// 离开页面销毁resize监听事件window.removeEventListener('resize', engineResize, false);})</script><template><div :class="isRendering ? 'containor bg' : 'containor'"><div id="loadingScreen" class="flex_column_center"><span class="loading"></span><span class="progress">{{ progress }}%</span><span class="text">3D模型加载中...</span></div><canvas id="canvas"></canvas><div class="btn_list flex_middle" v-if="isRendering"><el-button type="warning" size="small" @click="reset"><i class="el-icon-refresh"></i> 重置</el-button></div></div></template><style lang="scss" scoped>/*scrollbar styles*/::-webkit-scrollbar {width: 12px;height: 12px;// border-radius: 100px;}::-webkit-scrollbar-thumb {// border-radius: 100px;background: var(--color-ref-kl-primary10);}::-webkit-scrollbar-track-piece {// border-radius: 100px;background: transparent;}::-webkit-scrollbar-corner {background: transparent;}/*scrollbar styles*/#app {height: 100%;color: #4b4b4b;font-size: 13px;font-family: 'Microsoft YaHei';-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}.flex {display: flex;}.flex_center {@extend .flex;align-items: center;}.flex_left {@extend .flex_center;justify-content: flex-start;}.flex_right {@extend .flex_center;justify-content: flex-end;}.flex_middle {@extend .flex_center;justify-content: center;}.flex_column {@extend .flex;flex-direction: column;justify-content: center;}.flex_column_center {@extend .flex_column;align-items: center;}.public_radius {border-radius: 8px;}.echarts {height: 100%;overflow: hidden;}.containor {position: relative;width: 100%;height: 100%;overflow: hidden;&.bg {background-color: #8ecbe3;}#loadingScreen {position: absolute;width: 100%;height: 100%;.loading {display: inline-block;position: relative;width: 100px;height: 100px;border: 8px solid #0934f7;border-radius: 50%;animation: rotate 1s linear infinite;&:after {position: absolute;left: 50%;top: 50%;width: 110px;height: 110px;content: '';transform: translate(-50%, -50%);border: 8px solid transparent;border-bottom-color: #00eaff;border-radius: 50%;}}.progress {margin-top: -60px;color: #6be031;font-size: 16px;font-weight: 700;}.text {margin-top: 60px;color: #f5a327;font-size: 14px;}}canvas {width: 100%;height: 100%;outline: none;cursor: pointer;}.btn_list {position: absolute;bottom: 0;width: 100%;height: 50px;z-index: 99;button {margin: 0 15px 0 0;&:last-child {margin: 0;}}}.video_main {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);width: 800px;height: 500px;z-index: 999;video {outline: none;}}}</style>

Useful links

  • Official web site: www.babylonjs.com
  • Online playground to learn by experimentating
  • Online sandbox where you can test your .babylon and glTF scenes with a simple drag'n'drop
  • Online shader creation tool where you can learn how to create GLSL shaders
  • 3DS Max exporter can be used to generate a .babylon file from 3DS Max
  • Maya exporter can be used to generate a .babylon file from Maya
  • Blender exporter can be used to generate a .babylon file from Blender 3d
  • Unity 5 (deprecated) exporter can be used to export your geometries from Unity 5 scene editor(animations are supported)
  • glTF Tools by KhronosGroup

参见:

Babylon.js: Powerful, Beautiful, Simple, Open - Web-Based 3D At Its Best

Babylonjs中文网

GitHub - BabylonJS/Babylon.js: Babylon.js is a powerful, beautiful, simple, and open game and rendering engine packed into a friendly JavaScript framework.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/682343.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试经典150题——串联所有单词的子串(困难)

"Opportunities dont happen, you create them." ​ - Chris Grosser 1. 题目描述 2. 题目分析与解析 2.1 思路一——暴力求解 遇见这种可能刚开始没什么思路的问题&#xff0c;先试着按照人的思维来求解该题目。对于一个人来讲&#xff0c;我想要找到 s 字符串中…

AJAXJSON入门篇

AJAX&JSON 概念&#xff1a;AJAX(Asynchronous JavaScript And XML):异步的JavaScript和XML AJAX作用&#xff1a; 与服务器进行数据交换&#xff1a;通过AJAX可以给服务器发送请求&#xff0c;并获取服务器响应的数据 使用了AJAX和服务器进行通信&#xff0c;就可以使用H…

基于servlet编写的表白墙项目(后端代码 含数据库操作)

前提准备 项目前端代码和效果 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"…

java并发编程的艺术

java并发编程的艺术 第一章–并发的挑战 1。上下文切换 上下文切换是由于多任务操作系统需要管理多个线程或进程的并发 第二章—java并发机制的底层实现原理 java代码编译成字节码&#xff0c;然后被类加载器加载到jvm中&#xff0c;jvm执行&#xff0c;最终转换为汇编指令在cp…

C语言——枚举类型

&#x1f4dd;前言&#xff1a; 在之前的文章中我们已经讲解了自定义类型中的结构体类型和联合体类型&#xff0c;现在我们再充分学习一下C语言中的枚举类型&#xff1a; 1&#xff0c;什么是枚举类型 2&#xff0c;枚举类型的定义和变量的声明 3&#xff0c;对变量进行赋值 &a…

455. Assign Cookies(分发饼干)

题目描述 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j&#xff0c;都有一个…

每日OJ题_位运算⑦_力扣面试题 17.19. 消失的两个数字

目录 力扣面试题 17.19. 消失的两个数字 解析代码 力扣面试题 17.19. 消失的两个数字 面试题 17.19. 消失的两个数字 难度 困难 给定一个数组&#xff0c;包含从 1 到 N 所有的整数&#xff0c;但其中缺了两个数字。你能在 O(N) 时间内只用 O(1) 的空间找到它们吗&#xff…

OpenCompass 大模型评测

在浦语的大模型评测教程课程中&#xff0c;你可能需要完成的任务包括&#xff1a; 先修知识准备&#xff1a;这里你需要理解并掌握深度学习、NLP和PyTorch等相关知识。因为这些都是进行大模型评测的基础。模型理解&#xff1a;你需要对你要评测的模型有一个全面的理解&#xf…

FPGA实现ISP用于无人车、无人机配送的方案调研

查到一个always 奥唯思公司做的用FPGA实现ISP的方案&#xff0c;采用易灵思钛金16nm的FPGA Ti60F225&#xff0c;通过MIPI CSI RX采集图像传感器的数据&#xff0c;在FPGA内部经过一系列复杂的ISP运算后&#xff0c;再通过MIPI CSI TX将图像数据发送给后端。 一套完整的ISP&a…

【LeetCode】53. 最大子数组和(中等)——代码随想录算法训练营Day31

题目链接&#xff1a;53. 最大子数组和 题目描述 代码 测试用例 测试结果 测试结果 53. 最大子数组和 中等 相关标签 相关企业 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返…

uni-app生命周期 不说废话,直击重点 这篇就够了!

一、生命周期说明 uni-app的生命周期分为应用生命周期、页面生命周期、组件生命周期&#xff08;Vue的生命周期&#xff09; 二、应用生命周期 应用生命周期函数表&#xff1a; 函数名说明onLaunch初始化完成时触发&#xff08;全局只触发一次&#xff09;onShow启动或者从后…

【算法分析与设计】环形链表

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 题目 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次…

实景剧本杀小程序:创新体验,沉浸式推理乐趣

随着科技的飞速发展&#xff0c;人们对于娱乐方式的追求也在不断升级。传统的桌面剧本杀游戏已经不能满足玩家的需求&#xff0c;他们渴望更加真实、刺激的游戏体验。正是这种需求推动下&#xff0c;实景剧本杀小程序应运而生&#xff0c;为玩家带来前所未有的推理乐趣。 实景…

【基础】第K大与第K小数

说明 给定一个长度为N(0< n< 10000)的序列&#xff0c;保证每一个序列中的数字a[i]是正整数 &#xff0c;编程要求求出整个序列中第k大的数字减去第k小的数字的值m&#xff0c;并判断m是否为质数。(0< k< n) 输入数据 第一行为2个数n&#xff0c;k&#xff08;…

ChatGPT高效提问—prompt常见用法(续篇八)

ChatGPT高效提问—prompt常见用法(续篇八) 1.1 对抗 ​ 对抗是一个重要主题,深入探讨了大型语言模型(LLM)的安全风险。它不仅反映了人们对LLM可能出现的风险和安全问题的理解,而且能够帮助我们识别这些潜在的风险,并通过切实可行的技术手段来规避。 ​ 截至目前,网络…

【Android】使用Android Studio打包APK文件

文章目录 1. 新建项目2. 打包生成APK3. 安装APK 1. 新建项目 打包APK之前&#xff0c;首先需要新建项目&#xff0c;有基础的可以跳过。 无基础的可以参考&#xff1a;使用Android Studio运行Hello World项目 2. 打包生成APK 1.找到Build -> Generate Signed Bundle or …

AMD FPGA设计优化宝典笔记(4)复位桥

高亚军老师的这本书《AMD FPGA设计优化宝典》&#xff0c;他主要讲了两个东西&#xff1a; 第一个东西是代码的良好风格&#xff1b; 第二个是设计收敛等的本质。 这个书的结构是一个总论&#xff0c;加上另外的9个优化&#xff0c;包含的有&#xff1a;时钟网络、组合逻辑、触…

机器视觉范例及深入

1.做一个魔法棒吧 获得了物体的坐标后&#xff0c;可以用它来完成一些有趣的事情&#xff0c;例如把物体当作“笔”在图像 上绘制出图样。我们可以选择一种颜色的黏土&#xff0c;将其固定在任意棒状物&#xff08;例如铅笔&#xff09;的一端 并揉成球形&#xff0c;做一个 …

函数求导法则【高数笔记】

【分类】 1. 四则运算求导 2. 复合运算求导 3. 整体思想求导 #整体思想求导本质是运用复合运算求导&#xff0c;只不过是对复合运算求导的一种精炼 #无论是具体函数还是抽象函数求导&#xff0c;方法是一致的 【四则运算求导】 加&#xff0c;减&#xff0c;乘&#xff0c;除&a…