美文网首页js css htmlweb前端
three.js(25)-模型解压

three.js(25)-模型解压

作者: 姜治宇 | 来源:发表于2023-01-02 15:30 被阅读0次
    1.png

    在一些实战项目中,three只有几种有限的几何体,除非对细节不怎么要求,否则只能加载blender等工具导出的外部模型。在导入外部的模型时,经常会遇到各种各样的问题。

    加载模型报错

    我们使用GLTFLoader加载模型时,经常会遇到这样的错误: 7.png

    这是因为,模型是压缩过的,类似gzip,因此我们使用之前,需要先解压。
    DRACOLoader是three提供的模型解压工具,可以帮我们对模型进行解压操作。

        addGlb();
        async function addGlb() {
            const loader = new THREE.GLTFLoader();
            const dracoloader = getDracoLoader();
            loader.setDRACOLoader(dracoloader);//注入loader
            //加载地板
            const floor = await loadGlb('./model/floor2.glb', loader);
            scene.add(floor);
            //加载外墙
            const wall = await loadGlb('./model/wall.glb', loader);
            scene.add(wall);
        }
    
        function getDracoLoader() {
            //对模型解压
            const dracoloader = new THREE.DRACOLoader();
            dracoloader.setDecoderPath("./draco/");//把examples\jsm\libs\draco这个文件夹复制过来
            dracoloader.setDecoderConfig({ type: "js" })
            dracoloader.preload();
            return dracoloader;
        }
        function loadGlb(filepath, loader) {
            return new Promise((resolve, reject) => {
    
                loader.setCrossOrigin('Anonymous');//跨域问题
                loader.load(filepath, (glb) => {
    
                    resolve(glb.scene);
                }, undefined, (error) => {
    
                    console.error(error);
                    reject(error);
    
                });
            });
        }
    
    这里需要注意设置解压路径问题。我们需要把下载的E:\three.js-master\examples\jsm\libs\draco这个文件夹,复制到我们的项目中来,这个文件夹有一些写好的js工具类。 5.png

    模型是黑的

    加载出来的模型,即使打光了也是黑的。这是为啥呢?
    这是因为blender在转换时出现了材质丢失,我们可以在代码中进行补救。

    gltf.scene.traverse( function ( child ) {
      if ( child.isMesh ) {
        child.material.emissive =  child.material.color;
        child.material.emissiveMap = child.material.map ;
      }
    });
    

    全部代码:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="http://www.yanhuangxueyuan.com/threejs/build/three.min.js"></script>
        <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/controls/OrbitControls.js"></script>
        <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/GLTFLoader.js"></script>
        <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/DRACOLoader.js"></script>
    </head>
    
    <body>
        <div id="webgl"></div>
    
    </body>
    
    </html>
    <script>
        //场景
        var scene = new THREE.Scene();
        //相机设置为世界坐标原点
        var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(0, 0, 300);
        scene.add(camera);//添加相机
    
        //添加坐标轴
        var axes = new THREE.AxesHelper(500);//500表示xyz轴的长度,红:x,绿:y,蓝:z
        scene.add(axes);
        scene.add(new THREE.AmbientLight(0x444444));//打光
        addGlb();
        async function addGlb() {
            const loader = new THREE.GLTFLoader();
            const dracoloader = getDracoLoader();
            loader.setDRACOLoader(dracoloader);//注入loader
            //加载地板
            const floor = await loadGlb('./model/floor2.glb', loader);
            scene.add(floor);
            //加载外墙
            const wall = await loadGlb('./model/wall.glb', loader);
            
            scene.add(wall);
            //加载飞机
            const airplane = await loadGlb('./model/Fighter.glb', loader);
            airplane.position.y = 200;
            scene.add(airplane);
        }
    
        function getDracoLoader() {
            //对模型解压
            const dracoloader = new THREE.DRACOLoader();
            dracoloader.setDecoderPath("./draco/");//把examples\jsm\libs\draco这个文件夹复制过来
            dracoloader.setDecoderConfig({ type: "js" })
            dracoloader.preload();
            return dracoloader;
        }
        function loadGlb(filepath, loader) {
            return new Promise((resolve, reject) => {
    
                loader.setCrossOrigin('Anonymous');//跨域问题
                loader.load(filepath, (glb) => {
                    console.log('glb>>>', glb);
                    //处理材质丢失的情况
                    glb.scene.traverse(child => {
                        if (child.isMesh) {
                            child.material.emissive = child.material.color;
                            child.material.emissiveMap = child.material.map;
                        }
                    });
                    resolve(glb.scene);
                }, undefined, (error) => {
    
                    console.error(error);
                    reject(error);
    
                });
            });
        }
    
    
        var renderer = new THREE.WebGLRenderer({
            antialias: true,
            alpha: true
        });//画布
        renderer.setSize(window.innerWidth, window.innerHeight);//设置渲染区域尺寸
        renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    
        var controls = new THREE.OrbitControls(camera, renderer.domElement);
        //将渲染好的canvas追加到dom
        var cont = document.getElementById('webgl');
        cont.appendChild(renderer.domElement);
    
        animate();
    
        function animate() {
    
            renderer.render(scene, camera);//开始渲染
            requestAnimationFrame(animate);
    
        }
    
    
    
    </script>
    

    参考文章:https://blog.csdn.net/weixin_43131842/article/details/118025968
    https://zhuanlan.zhihu.com/p/350136476

    相关文章

      网友评论

        本文标题:three.js(25)-模型解压

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