首页 > 解决方案 > 将材质应用于 gltf 对象时出现未定义错误

问题描述

我创建了一个 Three.js 场景,它在 RGBELoader 中加载了一个 GLtf 对象(.glb)(用于 hdr 环境纹理照明)

然后我给这个 GLtf 对象内的每个网格一个新的材质。像这样:

              gltfObject.traverse((ChildGLTF) => {

              ChildGLTF.children[0].material = MidMaterial;
              ChildGLTF.children[1].material = TopMaterial;
              ChildGLTF.children[2].material = BotMaterial;
              
            });  

现在奇怪的是,我得到一个错误,同时材料按照我想要的方式应用。所以它确实有效。

我仍然想摆脱那个错误,或者至少了解是什么导致了它。

那是错误:

script.js:77 Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'material')
at script.js:77
at Mesh.traverse (three.module.js:6907)
at Group.traverse (three.module.js:6913)
at script.js:72
at GLTFLoader.js:175
at GLTFLoader.js:1989

所以我最好的猜测是,有不止一个 .material 属性?但是我怎么能指定,我只想要可变的材料..

或者,'gltfObject.traverse((ChildGLTF)' 以 ChildGLTF 作为数组运行不止一次?如果是这样,“console.log( ChildGLTF[0] );”给出“未定义”..

这是控制台日志

              console.log( ChildGLTF[0] ); //'undefined'
              console.log( ChildGLTF.children[0] ); //works fine
              console.log( ChildGLTF.children[0].material ); //'Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'material')'

console.log(ChildGLTF.children[0])

!Mesh {uuid: '3BE5076C-A90D-47B4-BE40-D1E77E4F4DEC', name: 'Cube', type: 'Mesh', parent: Group, children: Array(0), ...} 动画: [] castShadow: false children: [] frustumCulled:真实几何:BufferGeometry {uuid:'EC8A35A7-1942-4556-9D93-6C3E25F4C77A',名称:'',类型:'BufferGeometry',索引:BufferAttribute,属性:{...},...} 层:层 {掩码:1} 材质:MeshStandardMaterial {uuid:'ACA40D34-B763-42DA-A956-3ABBAC901D37',名称:'',类型:'MeshStandardMaterial',雾:真,混合:1,...} 矩阵:Matrix4 {元素:数组(16)} matrixAutoUpdate: true matrixWorld: Matrix4 {elements: Array(16)} matrixWorldNeedsUpdate: false name: "Cube" parent: Group {uuid: '27EE9C8E-3B31-4483-8058-CA2DA42070FC', name: 'Scene',类型:“组”,父级:

console.log(ChildGLTF.children[0].material);

!MeshStandardMaterial {uuid: 'FBA72EAB-93C3-4F92-B141-1BA011BB81FD', 名称: 'CubeMaterial', 类型: 'MeshStandardMaterial', 雾: true, 混合: 1, ...} alphaMap: null alphaTest: 0 aoMap: null aoMapIntensity: 1 blendDst: 205 blendDstAlpha: null blendEquation: 100 blendEquationAlpha: null blendSrc: 204 blendSrcAlpha: null blending: 1 bumpMap: null bumpScale: 1 clipIntersection: false clipShadows: false clippingPlanes: null color: Color {r: 0.011123105883598328, g: 0.004119289573282003 0.8000000715255737} colorWrite: true 定义: {STANDARD: ''} depthFunc: 3 depthTest: true depthWrite: truedisplacementBias:0displacementMap:nulldisplacementScale:1dithering:false emissive:Color {r:0,g:0,b:0} emissiveIntensity: 1 emissiveMap: null envMap: null envMapIntensity: 1 flatShading: false 雾: true lightMap:

标签: three.jsgltf

解决方案


.traverse(...)将为模型中的每个对象运行该回调,并且您的代码假定每个对象恰好具有三个子对象。这是不可能的,因为模型必须无限深,当你最终到达一个没有子对象的对象时,doing.children[0].material会抛出这些错误。

您需要检查是什么ChildGLTF,并且在循环期间修改该对象。

gltfObject.traverse((child) => {
  if (!child.isMesh) return;

  if (child.name === 'MyMidMeshName') { // change this name
    child.material = MidMaterial;
  } else if (child.name === 'MyTopMeshName') { // change this name
    // ...
  } else {
    // ...
  }
});

推荐阅读