当前位置:首页 » 《休闲阅读》 » 正文

vue3 + Babylon.js 构建Web 3D场景

19 人参与  2024年05月02日 08:51  分类 : 《休闲阅读》  评论

点击全文阅读


<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 engine    engine = 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();    // 初始化一个场景 scene    scene = new BABYLON.Scene(engine);    // 设置背景色透明    scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);    // 初始化相机 camera    camera = 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;    });    // 注册渲染循环 runRenderLoop    engine.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.comOnline playground to learn by experimentatingOnline sandbox where you can test your .babylon and glTF scenes with a simple drag'n'dropOnline shader creation tool where you can learn how to create GLSL shaders3DS Max exporter can be used to generate a .babylon file from 3DS MaxMaya exporter can be used to generate a .babylon file from MayaBlender exporter can be used to generate a .babylon file from Blender 3dUnity 5 (deprecated) exporter can be used to export your geometries from Unity 5 scene editor(animations are supported)glTF Tools by KhronosGroup

    "@babylonjs/core": "^5.24.0",

    "@babylonjs/gui": "^5.24.0",

    "@babylonjs/loaders": "^5.24.0",

    "@babylonjs/materials": "^5.24.0",

    "@babylonjs/post-processes": "^5.24.0",

    "@babylonjs/procedural-textures": "^5.24.0",

    "@babylonjs/serializers": "^5.24.0",

    "@babylonjs/viewer": "^5.24.0",

参见:

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.

Export To Babylon.js


点击全文阅读


本文链接:http://zhangshiyu.com/post/102773.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1