美文网首页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)-模型解压

    在一些实战项目中,three只有几种有限的几何体,除非对细节不怎么要求,否则只能加载blender等工具导出的外部...

  • Three.js模型隐藏或显示

    Three.js模型隐藏或显示 个人技术博客 你在使用Three.js开发项目的过程中,可能需要隐藏一个模型,或者...

  • Three.js模型标签

    Three.js模型标签 在很多的实际的项目中,你可能需要给一个Three.js的模型添加标签,标签可以通过一个包...

  • 15three.js加载obj模型

    three.js加载obj模型 varscene =newTHREE.Scene(); varloader =ne...

  • Three.js跨域问题(无法预览)

    Three.js跨域问题 通过Three.js加载obj、FBX等格式外部模型文件的时候是ajax异步加载数据的过...

  • MTLLoader 报 Handlers.get() has b

    使用Three.js加载外部模型(OBJ,JSON...等格式的模型文件)。 上代码: yarn add thre...

  • 考前解压模型

    考前解压模型 一、 收回投射法 1、 给压力打分:如果要高考了,压力满分是10分,你给这个压力打几分 2、 施压者...

  • 将不同格式的3d模型导入three.js

    three.js除了可以自己绘画3d模型以外,当然也是可以自己导入3d模型。官方提供了许多例子,多且难寻。于是体贴...

  • Cesium.js 初试

    今天讲下Cesium,说起来,用这个是因为模型,three.js用起来一直没有找到能加载模型的方法,所以就用Ces...

  • three.js模型拖拽旋转

    通过判断鼠标像素坐标与模型中心点像素坐标进行计算角度(three.js版本125) mousedown(e){ t...

网友评论

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

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