three.js - 将材质应用于 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:
解决方案
.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 {
// ...
}
});
推荐阅读
- javascript - 在 NextJS 中导入 SVG
- javascript - JS本地网络通信
- vega - Vega-lite Transforms 中的多重聚合
- instagram - Instagram:access_token 无效
- javascript - Material UI 中的自定义操作选择 MenuItem
- angular - 使用自定义颜色主题化 Angular 材质
- javascript - 从 FormControl 中的 mat-datepicker 中获取价值
- javascript - 如何防止 Firebase 实时数据库、Web、JavaScript 的数据重复
- python - 附加两个数据框并创建一个新的
- javascript - 在 Safari 中缩小时文本无法正确缩放