使用FBXLoader时报Cannot read properties of undefined (reading 'elements')如何解决
问题根因
Uncaught TypeError: Cannot read properties of undefined (reading 'elements')报错触发原因:部分Mesh节点的material属性为空,或是多材质数组,代码直接访问child.material.map拿到undefined值,传入新材质的map参数后,Three.js渲染时读取纹理的elements属性失败触发报错。- 带阴影纹理的轮子、平面无法显示的原因:统一将原材质替换为仅保留color、map属性的MeshPhongMaterial,丢失了原材质的透明通道、法线贴图、阴影配置等属性,使用多材质的复合Mesh节点被替换为单材质后也会出现结构渲染丢失的问题。
修复后代码
const loader = new FBXLoader(); @foreach ($files as $file) @if (strtolower(pathinfo($file, PATHINFO_EXTENSION)) == 'fbx') loader.setResourcePath('storage/models/{{ $modelId }}/').load('storage/{{ $file }}', function ( object ) { object.traverse( function ( child ) { // 先判断Mesh和material存在再做处理 if ( child.isMesh && child.material ) { // 兼容单材质、多材质两种场景 const processSingleMaterial = (originMat) => { if(!originMat) return originMat; return new THREE.MeshPhongMaterial( { color: 0xffffff, map: originMat.map || null, // 保留原材质必要配置,避免效果丢失 transparent: originMat.transparent, opacity: originMat.opacity, alphaMap: originMat.alphaMap, normalMap: originMat.normalMap, side: originMat.side, shadowSide: THREE.DoubleSide } ); } if (Array.isArray(child.material)) { child.material = child.material.map(mat => processSingleMaterial(mat)) } else { child.material = processSingleMaterial(child.material) } child.receiveShadow = true; child.castShadow = true; } } ); object.receiveShadow = true; object.castShadow = true; scene.add( object ); } ); @endif @endforeach
额外排查点
- 确认
storage/models/{{ $modelId }}/路径下存放了FBX依赖的所有纹理资源,资源路径错误会导致纹理加载失败也会触发同类报错 - 如果你没有强制替换材质的需求,可以直接修改原材质的相关属性,不需要重新实例化MeshPhongMaterial,最大程度避免属性丢失
内容的提问来源于stack exchange,提问作者Anton Shmetelko
相关产品推荐
相关产品推荐

