将材质应用于 gltf 对象时出现未定义错误
Undefined Error when applying materials to gltf object
我创建了一个 Three.js 场景,它在 RGBELoader 中加载了一个 GLtf 对象 (.glb)(用于 hdr 环境纹理照明)
然后我给这个 GLtf 对象中的每个网格一个新的 Material。像这样:
gltfObject.traverse((ChildGLTF) => {
ChildGLTF.children[0].material = MidMaterial;
ChildGLTF.children[1].material = TopMaterial;
ChildGLTF.children[2].material = BotMaterial;
});
现在奇怪的是,我得到了一个错误,同时 material 应用了我想要的。所以它确实有效。
我仍然想消除该错误或至少了解导致错误的原因。
那是错误:
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 属性?但是我如何指定,我只想要可变的 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), …}
animations: []
castShadow: false
children: []
frustumCulled: true
geometry: BufferGeometry {uuid: 'EC8A35A7-1942-4556-9D93-6C3E25F4C77A', name: '', type: 'BufferGeometry', index: BufferAttribute, attributes: {…}, …}
layers: Layers {mask: 1}
material: MeshStandardMaterial {uuid: 'ACA40D34-B763-42DA-A956-3ABBAC901D37', name: '', type: 'MeshStandardMaterial', fog: true, blending: 1, …}
matrix: Matrix4 {elements: Array(16)}
matrixAutoUpdate: true
matrixWorld: Matrix4 {elements: Array(16)}
matrixWorldNeedsUpdate: false
name: "Cube"
parent: Group {uuid: '27EE9C8E-3B31-4483-8058-CA2DA42070FC', name: 'Scene', type: 'Group', parent: Scene, children: Array(3), …}
position: Vector3 {x: 0, y: 0, z: 0}
quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, _onChangeCallback: ƒ}
receiveShadow: false
renderOrder: 0
rotation: Euler {_x: 0, _y: 0, _z: 0, _order: 'XYZ', _onChangeCallback: ƒ}
scale: Vector3 {x: 1, y: 1, z: 1}
type: "Mesh"
up: Vector3 {x: 0, y: 1, z: 0}
userData: {name: 'Cube'}
uuid: "3BE5076C-A90D-47B4-BE40-D1E77E4F4DEC"
visible: true
drawMode: (...)
eulerOrder: (...)
id: 40
modelViewMatrix: Matrix4 {elements: Array(16)}
normalMatrix: Matrix3 {elements: Array(9)}
useQuaternion: (...)
[[Prototype]]: Object3D
console.log(ChildGLTF.children[0].material);
! MeshStandardMaterial {uuid: 'FBA72EAB-93C3-4F92-B141-1BA011BB81FD', name: 'CubeMaterial', type: 'MeshStandardMaterial', fog: true, blending: 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, b: 0.8000000715255737}
colorWrite: true
defines: {STANDARD: ''}
depthFunc: 3
depthTest: true
depthWrite: true
displacementBias: 0
displacementMap: null
displacementScale: 1
dithering: false
emissive: Color {r: 0, g: 0, b: 0}
emissiveIntensity: 1
emissiveMap: null
envMap: null
envMapIntensity: 1
flatShading: false
fog: true
lightMap: null
lightMapIntensity: 1
map: null
metalness: 0
metalnessMap: null
morphNormals: false
morphTargets: false
name: "CubeMaterial"
normalMap: null
normalMapType: 0
normalScale: Vector2 {x: 1, y: 1}
opacity: 1
polygonOffset: false
polygonOffsetFactor: 0
polygonOffsetUnits: 0
precision: null
premultipliedAlpha: false
refractionRatio: 0.98
roughness: 0.5
roughnessMap: null
shadowSide: null
side: 2
skinning: false
stencilFail: 7680
stencilFunc: 519
stencilFuncMask: 255
stencilRef: 0
stencilWrite: false
stencilWriteMask: 255
stencilZFail: 7680
stencilZPass: 7680
toneMapped: true
transparent: false
type: "MeshStandardMaterial"
userData: {}
uuid: "FBA72EAB-93C3-4F92-B141-1BA011BB81FD"
version: 0
vertexColors: false
vertexTangents: false
visible: true
wireframe: false
wireframeLinecap: "round"
wireframeLinejoin: "round"
wireframeLinewidth: 1
id: 7
overdraw: (...)
shading: (...)
stencilMask: (...)
wrapAround: (...)
wrapRGB: (...)
[[Prototype]]: Material
.traverse(...)
将 运行 模型中每个 object 的回调,并且您的代码假定每个 object 恰好有三个 children。这是不可能的,因为模型必须无限深,当你最终到达一个没有 children 的 object 时,做 .children[0].material
会抛出这些错误。
您需要检查 ChildGLTF
是什么,并且 仅 在循环期间修改那个 object。
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 {
// ...
}
});
我创建了一个 Three.js 场景,它在 RGBELoader 中加载了一个 GLtf 对象 (.glb)(用于 hdr 环境纹理照明)
然后我给这个 GLtf 对象中的每个网格一个新的 Material。像这样:
gltfObject.traverse((ChildGLTF) => {
ChildGLTF.children[0].material = MidMaterial;
ChildGLTF.children[1].material = TopMaterial;
ChildGLTF.children[2].material = BotMaterial;
});
现在奇怪的是,我得到了一个错误,同时 material 应用了我想要的。所以它确实有效。
我仍然想消除该错误或至少了解导致错误的原因。
那是错误:
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 属性?但是我如何指定,我只想要可变的 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), …} animations: [] castShadow: false children: [] frustumCulled: true geometry: BufferGeometry {uuid: 'EC8A35A7-1942-4556-9D93-6C3E25F4C77A', name: '', type: 'BufferGeometry', index: BufferAttribute, attributes: {…}, …} layers: Layers {mask: 1} material: MeshStandardMaterial {uuid: 'ACA40D34-B763-42DA-A956-3ABBAC901D37', name: '', type: 'MeshStandardMaterial', fog: true, blending: 1, …} matrix: Matrix4 {elements: Array(16)} matrixAutoUpdate: true matrixWorld: Matrix4 {elements: Array(16)} matrixWorldNeedsUpdate: false name: "Cube" parent: Group {uuid: '27EE9C8E-3B31-4483-8058-CA2DA42070FC', name: 'Scene', type: 'Group', parent: Scene, children: Array(3), …} position: Vector3 {x: 0, y: 0, z: 0} quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, _onChangeCallback: ƒ} receiveShadow: false renderOrder: 0 rotation: Euler {_x: 0, _y: 0, _z: 0, _order: 'XYZ', _onChangeCallback: ƒ} scale: Vector3 {x: 1, y: 1, z: 1} type: "Mesh" up: Vector3 {x: 0, y: 1, z: 0} userData: {name: 'Cube'} uuid: "3BE5076C-A90D-47B4-BE40-D1E77E4F4DEC" visible: true drawMode: (...) eulerOrder: (...) id: 40 modelViewMatrix: Matrix4 {elements: Array(16)} normalMatrix: Matrix3 {elements: Array(9)} useQuaternion: (...) [[Prototype]]: Object3D
console.log(ChildGLTF.children[0].material);
! MeshStandardMaterial {uuid: 'FBA72EAB-93C3-4F92-B141-1BA011BB81FD', name: 'CubeMaterial', type: 'MeshStandardMaterial', fog: true, blending: 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, b: 0.8000000715255737} colorWrite: true defines: {STANDARD: ''} depthFunc: 3 depthTest: true depthWrite: true displacementBias: 0 displacementMap: null displacementScale: 1 dithering: false emissive: Color {r: 0, g: 0, b: 0} emissiveIntensity: 1 emissiveMap: null envMap: null envMapIntensity: 1 flatShading: false fog: true lightMap: null lightMapIntensity: 1 map: null metalness: 0 metalnessMap: null morphNormals: false morphTargets: false name: "CubeMaterial" normalMap: null normalMapType: 0 normalScale: Vector2 {x: 1, y: 1} opacity: 1 polygonOffset: false polygonOffsetFactor: 0 polygonOffsetUnits: 0 precision: null premultipliedAlpha: false refractionRatio: 0.98 roughness: 0.5 roughnessMap: null shadowSide: null side: 2 skinning: false stencilFail: 7680 stencilFunc: 519 stencilFuncMask: 255 stencilRef: 0 stencilWrite: false stencilWriteMask: 255 stencilZFail: 7680 stencilZPass: 7680 toneMapped: true transparent: false type: "MeshStandardMaterial" userData: {} uuid: "FBA72EAB-93C3-4F92-B141-1BA011BB81FD" version: 0 vertexColors: false vertexTangents: false visible: true wireframe: false wireframeLinecap: "round" wireframeLinejoin: "round" wireframeLinewidth: 1 id: 7 overdraw: (...) shading: (...) stencilMask: (...) wrapAround: (...) wrapRGB: (...) [[Prototype]]: Material
.traverse(...)
将 运行 模型中每个 object 的回调,并且您的代码假定每个 object 恰好有三个 children。这是不可能的,因为模型必须无限深,当你最终到达一个没有 children 的 object 时,做 .children[0].material
会抛出这些错误。
您需要检查 ChildGLTF
是什么,并且 仅 在循环期间修改那个 object。
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 {
// ...
}
});