首页 前端知识 Uniapp中three.js初使用(加载fbx或者glb)

Uniapp中three.js初使用(加载fbx或者glb)

2024-09-28 23:09:54 前端知识 前端哥 148 670 我要收藏
  1. 安装three包,我选择的0.149.0版本 
     
    npm install --save three@0.149.0
    复制

  2. 页面引入three.js

    import * as THREE from 'three'
    import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'
    import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js';
    import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader.js';
    复制

  3. 创建three.js场景

    init() {
    // 创建一个场景
    this.scene = new THREE.Scene()
    //三位坐标线
    // const axesHelper = new THREE.AxesHelper(5);
    // this.scene.add(axesHelper);
    //创建相机对象,45是相机的视角 , 宽高比是屏幕的宽高比 , 最近能看到0.1 , 最远能看到10000
    // this.camera = new THREE.OrthographicCamera(-s * k, s * k, s , -s, 1, 1000);
    // this.camera.position.set(0, 20, 300);
    this.camera = new THREE.PerspectiveCamera()
    //100,300 ,500
    this.camera.position.set(500, 0, 700); //设置相机位置
    // this.camera.position.set(100, -800, 500);
    // this.scene.position.set(0,40,0)
    console.log(this.scene.position)
    this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象)
    // 执行一个渲染函数
    this.rendererGLR()
    /* 光源设置*/
    this.pointLight()
    this.clock = new THREE.Clock()
    //创建控件对象
    this.change()
    //更新轨道控件
    this.animate()
    let fileName = this.modelUrl.lastIndexOf(".")
    let fileFormat = this.modelUrl.substring(fileName + 1, this.modelUrl.length).toLowerCase()
    if (fileFormat == 'fbx') {
    this.fbxLoader()
    } else if(fileFormat == 'glb') {
    this.gblLoader()
    }
    this.renderer.render(this.scene, this.camera);
    },
    复制

  4. 渲染

    //渲染函数
    rendererGLR(){
    this.$nextTick(() => {
    const element = document.getElementById('threeView')
    this.renderer.setSize(element.clientWidth, element.clientHeight);
    element.appendChild(this.renderer.domElement);
    })
    this.renderer = new THREE.WebGLRenderer({alpha:true, antialias: true});//alpha:true背景透明
    this.renderer.setPixelRatio( window.devicePixelRatio * 2);
    this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
    this.renderer.toneMappingExposure = 1.0;
    this.renderer.shadowMap.enabled = true;
    this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    },
    复制

  5. 设置光源 (我这边设置的是四束光源)

    let ambientLight = new THREE.AmbientLight(0xffffff,1);
    this.scene.add(ambientLight);
    const directional_light = new THREE.DirectionalLight( 0xffffff, 1 );
    directional_light.position.set( 0, 1, 0 );
    directional_light.castShadow = true;
    this.scene.add(directional_light);
    let a=1,b=0.6,c=10;
    let directionalLight1 = new THREE.DirectionalLight(0xffffff,b);
    directionalLight1.position.set(-a,-a ,a*c).normalize();
    let directionalLight2 = new THREE.DirectionalLight(0xffffff,b);
    directionalLight2.position.set(a,-a,-a*c).normalize();
    let directionalLight3 = new THREE.DirectionalLight(0xffffff,b);
    directionalLight3.position.set(-a,a,-a*c).normalize();
    let directionalLight4 = new THREE.DirectionalLight(0xffffff,b);
    directionalLight4.position.set(a,a,a*c).normalize();
    this.scene.add(directionalLight1);
    this.scene.add(directionalLight2);
    this.scene.add(directionalLight3);
    this.scene.add(directionalLight4);
    复制

  6. 创建控件对象,这步主要是为了可以手动控制3D旋转,放大缩小等效果

    //创建控件对象
    change(){
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    this.controls.minDistance = 300
    this.controls.maxDistance = 1000
    this.controls.addEventListener('change', () => {
    this.renderer.render(this.scene, this.camera);
    }); //监听鼠标、键盘事件
    //禁止缩放
    this.controls.enableZoom = this.changeFlag
    //禁止旋转
    this.controls.enableRotate = this.changeFlag
    //禁止右键拖拽
    this.controls.enablePan = this.changeFlag
    },
    复制

  7. 创建轨道控件(这一步是为了3D效果自旋转)

    //更新轨道控件
    animate() {
    if (this.renderer) {
    // console.log(this.stats)
    // this.stats.update()
    let T = this.clock.getDelta()
    let renderT = 1 / 30
    this.timeS = this.timeS + T
    if(this.timeS > renderT) {
    this.controls.update();
    this.renderer.render(this.scene, this.camera);
    this.timeS = 0
    }
    requestAnimationFrame(this.animate);
    if (!this.changeFlag) {
    this.controls.autoRotateSpeed = 15
    }
    this.controls.autoRotate = true // 是否自动旋转
    }
    //创建一个时钟对象
    // this.clock = new THREE.Clock()
    // this.scene.rotateY(0.01)
    //获得两帧的时间间隔 更新混合器相关的时间
    // if (this.mixer) {this.mixer.update(this.clock.getDelta())}
    },
    复制

  8. 根据不同的文件类型使用不同的方法导入

    //导入FBX模型文件
    fbxLoader(){
    let that=this
    const loader = new FBXLoader();
    loader.load(this.modelUrl,function(mesh){
    that.scene.add(mesh);
    that.ownerInstance.callMethod('onload')
    })
    },
    //导入GLB模型文件
    gblLoader(){
    let that=this
    const loader = new GLTFLoader();
    loader.load(this.modelUrl, function(gltf) {
    console.log(gltf)
    that.mesh = gltf.scene
    let model = gltf.scene
    that.scene.add(model);
    that.ownerInstance.callMethod('onload')
    });
    },
    复制

  9. 注意事项:该效果在uniapp只能在H5运行,在APP运行需要使用renderjs 这个我后续应该会有文章出来说明

转载请注明出处或者链接地址:https://www.qianduange.cn//article/18680.html
标签
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!