You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在loader.load外部访问Three.js加载的GLB/GLTF模型?

解决Three.js中dat.gui无法访问异步加载模型材质的问题

你猜的没错,问题根源就是GLB模型是异步加载的。loader.load()是异步方法,它不会阻塞后续代码执行——也就是说,dat.gui的onChange回调可能在模型加载完成前就被触发,这时model还没被赋值,自然会报"Cannot set properties of undefined"的错误。另外你代码里还有个小问题:model是你赋值的gltf对象,它本身没有material属性,材质在gltf场景下的网格(Mesh)对象里。

解决方法

  • 方法一:等待模型加载完成后再创建GUI控制器
    把GUI相关的代码移到loader.load的成功回调里,确保模型加载完成后再绑定控制器:

    let model
    const options = { wireframe: false}
    
    loader.load('new.glb', function(gltf){
      model = gltf
      scene.add(gltf.scene)
      // 模型加载完成后再创建GUI控制器
      gui.add(options, 'wireframe').onChange(function(e){
        // 遍历场景中的所有Mesh,设置wireframe
        model.scene.traverse(obj => {
          if(obj.isMesh){
            obj.material.wireframe = e
          }
        })
      })
    }, undefined, function (error) {
      console.error(error)
    })
    
  • 方法二:在回调中检查模型是否存在,并正确获取材质
    如果你需要提前创建GUI控制器,可以在onChange回调里先判断model是否已初始化,同时遍历场景中的网格设置材质:

    let model
    const options = { wireframe: false}
    
    loader.load('new.glb', function(gltf){
      model = gltf
      scene.add(gltf.scene)
    }, undefined, function (error) {
      console.error(error)
    })
    
    gui.add(options, 'wireframe').onChange(function(e){
      // 先检查model是否存在
      if(!model) return
      // 遍历场景中的所有Mesh,设置wireframe
      model.scene.traverse(obj => {
        if(obj.isMesh){
          obj.material.wireframe = e
        }
      })
    })
    

补充说明

GLB模型导出的场景通常是一个THREE.Group,里面可能包含多个Mesh对象,直接访问model.material是错误的。必须用traverse方法遍历场景中的所有对象,筛选出isMesh为true的网格,再设置它们的材质属性。

内容的提问来源于stack exchange,提问作者oldboy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:48:18