【问题标题】:How to override GLTF materials in three.js如何在three.js中覆盖GLTF材质
【发布时间】:2019-11-01 18:36:26
【问题描述】:

我正在尝试创建一种动态方式来在 three.js 中的 gltf 导入模型上显示太阳能数据。目的是将不同的纯色与模型的不同部分相关联,并能够将它们关闭和打开。我目前的障碍是改变 gltf 中材质的颜色。

我尝试过使用 ObjLoader 来输入我自己的材料,但这不起作用:/

这是我目前拥有的js:

        const gltfLoader = new THREE.GLTFLoader();
        gltfLoader.load('Building.glb', (gltf) => {
            const root = gltf.scene;
            scene.add(root);

            const box = new THREE.Box3().setFromObject(root);
            const boxSize = box.getSize(new THREE.Vector3()).length();
            const boxCenter = box.getCenter(new THREE.Vector3());

            frameArea(boxSize * 0.5, boxSize, boxCenter, camera);

            controls.maxDistance = boxSize * 10;
            controls.target.copy(boxCenter);
            controls.update();
          });


    function frameArea(sizeToFitOnScreen, boxSize, boxCenter, camera) {
        const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
        const halfFovY = THREE.Math.degToRad(camera.fov * .5);
        const distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
        const direction = (new THREE.Vector3())
        .subVectors(camera.position, boxCenter)
        .multiply(new THREE.Vector3(1, 0, 1))
        .normalize();

        camera.position.copy(direction.multiplyScalar(distance).add(boxCenter));

        camera.near = boxSize / 100;
        camera.far = boxSize * 100;

        camera.updateProjectionMatrix();

        // point the camera to look at the center of the box
        camera.lookAt(boxCenter.x, boxCenter.y, boxCenter.z);
    }

    renderer = new THREE.WebGLRenderer({canvas: myCanvas, antialias: true});
    renderer.setClearColor(0x000000);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild( renderer.domElement );



    function resizeRendererToDisplaySize(renderer) {
        const canvas = renderer.domElement;
        const width = canvas.clientWidth;
        const height = canvas.clientHeight;
        const needResize = canvas.width !== width || canvas.height !== height;
        if (needResize) {
          renderer.setSize(width, height, false);
      }
      return needResize;
    }

    function render() {
        if (resizeRendererToDisplaySize(renderer)) {
            const canvas = renderer.domElement;
            camera.aspect = canvas.clientWidth / canvas.clientHeight;
             camera.updateProjectionMatrix();
            }
            renderer.render(scene, camera);
            requestAnimationFrame(render);
         }
         requestAnimationFrame(render);

【问题讨论】:

    标签: three.js rhino gltf grasshopper


    【解决方案1】:

    作为上述答案的补充,gltf.scene 不对应于THREE.Scenegltf.sceneTHREE.Group 实例,但您应该能够如上所述遍历。 https://github.com/mrdoob/three.js/blob/94f043c4e105eb73236529231388402da2b07cba/examples/jsm/loaders/GLTFLoader.js#L3890

    对于 Three.js,最好使用 GLTFLoader 加载模型,因为 Wavefront (.obj) 格式仅支持几何数据。它不能存储材料、动画等其他东西,这很可能是它不适合你的原因。

    正如 Don 所说,您最好的方法是遍历 gltf.scene 并单独访问网格(根据 GLTFLoader 代码,网格应根据 gltf 文件中的导出名称命名,因此您应该能够识别如果您使用诸如 blender 或 maya 之类的 DCC 应用程序来命名网格,则使用 mesh.name 属性。

    【讨论】:

      【解决方案2】:

      加载器返回的gltf.scene 结果是一个THREE.Scene 实例——一旦你有了它,用什么文件格式来加载模型并不重要。在这种情况下,您需要遍历该场景并更改其中任何网格的材质。 MeshStandardMaterialMesh 文档可能会有所帮助。

      var model = gltf.scene;
      var newMaterial = new THREE.MeshStandardMaterial({color: 0xff0000});
      model.traverse((o) => {
        if (o.isMesh) o.material = newMaterial;
      });
      

      如果您需要更改纹理,请注意GLTFLoader documentation 中的说明。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-30
        • 1970-01-01
        • 1970-01-01
        • 2019-04-20
        • 2020-08-19
        • 2019-02-13
        • 2018-08-27
        • 2017-09-27
        相关资源
        最近更新 更多