美文网首页
vite+vue3+threejs实现一个3D模型的展示案例

vite+vue3+threejs实现一个3D模型的展示案例

作者: 似朝朝我心 | 来源:发表于2022-04-18 10:01 被阅读0次

    1.检查npm -v版本和使用对应的vite安装vue3项目

    # npm 6.x
    npm init vite@latest my-vue-app --template vue
    
    # npm 7+, 需要额外的双横线:
    npm init vite@latest my-vue-app -- --template vue
    

    需要安装依赖:npm install
    运行:npm run dev
    目录结构:


    2.threejs官网:

    https://threejs.org/
    

    3.安装threejs

    npm install --save three
    

    4.准备3D模型素材(我这里使用glb格式)和HDR图片,素材网上可以找有免费的。


    这里推荐一些网站:
    jpg转hdr网站: https://cn.office-converter.com/how-to-convert-jpeg-to-hdr
    免费的hdr图网站:https://tietu.znzmo.com/tietu/hdrtietu_m/p_1.html?color=0
    免费的hdr图网站:https://tt.qingmo.com/8/0_0_1_1_0_0.html
    ps可以将hdr到处为jpg等格式
    免费的fbx模型:https://www.cg99.com/models/
    免费的gltf模型:http://glbxz.com/
    

    5.在App.vue中绑定id,挂载,实例化使用

    <template>
        <div class="scene" id="scene"></div>
    </template>
    
    <script setup>
    import Base3d from './utils/Base3d';
    import { reactive,onMounted } from 'vue';
    const data = reactive({
        base3d:{}
    })
    onMounted(()=>{
        data.base3d = new Base3d('#scene')
    })
    </script>
    
    <style>
    *{
        margin:0;
        padding: 0;
    }
    </style>
    

    6.在项目中的src目录下创建utils目录,在utils目录下创建Base3d.js脚本

    import * as THREE from 'three' //导入整个 three.js核心库
    import { EquirectangularReflectionMapping } from 'three' //导入纹理映射模块
    import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader' //导入RGB加载器
    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' //导入控制器模块,轨道控制器
    import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' //导入GLTF模块,模型解析器,根据文件格式来定
    
    
    class Base3d {
        constructor(selector) {
            this.container = document.querySelector(selector)
            this.camera
            this.scene
            this.renderer
            this.controls
            this.init()
            this.animate()
        }
        init() {
            //初始化场景
            this.initScene()
            //初始化相机
            this.initCamera()
            //初始化渲染器
            this.initRender()
            //初始化控制器,控制摄像头,控制器一定要在渲染器后
            this.initControls()
            // 添加物体模型
            this.addMesh()
            //监听场景大小改变,跳转渲染尺寸
            window.addEventListener("resize", this.onWindowResize.bind(this))
        }
        initScene() {
            this.scene = new THREE.Scene()
            this.setEnvMap('079')
        }
        initCamera() {
            this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.25, 200)
            this.camera.position.set(-1.8, 0.6, 20)
        }
        initRender() {
            this.renderer = new THREE.WebGLRenderer({ antialias: true }) //设置抗锯齿
            //设置屏幕像素比
            this.renderer.setPixelRatio(window.devicePixelRatio)
            //渲染的尺寸大小
            this.renderer.setSize(window.innerWidth, window.innerHeight)
            //色调映射
            this.renderer.toneMapping = THREE.ACESFilmicToneMapping
            //曝光
            this.renderer.toneMappingExposure = 3
            this.container.appendChild(this.renderer.domElement)
        }
        setEnvMap(hdr) { //设置环境背景
            new RGBELoader().setPath('./files/hdr/').load(hdr+'.hdr', (texture) => {
                texture.mapping = EquirectangularReflectionMapping  //圆柱形形纹理映射
                this.scene.background = texture
                this.scene.environment = texture
            })
        }
        render() {
            this.renderer.render(this.scene, this.camera)
        }
        animate() {
            this.renderer.setAnimationLoop(this.render.bind(this))
        }
        initControls() {
            this.controls = new OrbitControls(this.camera, this.renderer.domElement)
        }
        //加载模型
        setModel(modelName) {
            return new Promise((resolve, reject) => {
                const loader = new GLTFLoader().setPath('files/gltf/')
                loader.load(modelName, (gltf) => {
                    console.log(gltf);
                    this.model = gltf.scene.children[0]
                    this.scene.add(this.model)
                    resolve(this.modelName + '模型添加成功')
                })
            })
        }
        addMesh() {
            this.setModel('phone.glb')
        }
        onWindowResize() { //调整屏幕大小
            this.camera.aspect = window.innerWidth / window.innerHeight //摄像机宽高比例
            this.camera.updateProjectionMatrix() //相机更新矩阵,将3d内容投射到2d面上转换
            this.renderer.setSize(window.innerWidth, window.innerHeight)
        }
    }
    export default Base3d
    

    效果展示:手机模型已经加载至场景中,背景是hdr图。
    功能展示:用户可以滑动滚轮将模型进行放大缩小,场景360度无死角旋转。


    相关文章

      网友评论

          本文标题:vite+vue3+threejs实现一个3D模型的展示案例

          本文链接:https://www.haomeiwen.com/subject/hcarertx.html