You need to enable JavaScript to run this app. React Three Fiber多网格渲染异常:仅最后一个组件GLTF模型正常显示
优惠活动
大模型
产品
解决方案
定价
更多

React Three Fiber多网格渲染异常:仅最后一个组件GLTF模型正常显示

异常核心根因

Three.js 引擎本身的设计规则是:同一个 Object3D 实例在同一场景树中,只能挂载在一个父节点下,不存在“一个对象同时出现在多个位置”的能力。
你当前的实现里,所有 ITEM 组件调用 useGLTF(modelPath) 时,由于传入的模型路径完全相同,useGLTF 内部的资源缓存机制会直接返回同一份全局缓存的 gltf.scene 实例,不会为每个组件生成独立副本。当你把这个同一个 scene 实例依次通过 <primitive> 挂载到每个 ITEM 的场景节点下时,后一次的挂载操作会自动把该实例从之前的父节点中移除,最终只有最后一个完成挂载的 ITEM 能持有这个模型实例,其余组件的模型自然会丢失。

排查步骤
  • 先通过变量验证根因:临时给两个相邻的 ITEM 传入不同的模型路径,比如第一个传 /model/a.gltf,第二个传 /model/b.gltf,如果两个模型都能正常渲染,就可以确认是同一份资源被重复挂载导致的问题。
  • 全局检索代码里直接复用 Three.js 对象引用的位置:不管是通过 useGLTF 获取的缓存对象,还是手动实例化的 Three.js 对象,只要是同一个引用被多次传入 <primitive> 的 object 属性,都会触发同类问题。

解决方案

根据你的业务场景选择对应实现:

1. 需独立操作多份相同模型(适配你当前每个模型独立转动、独立交互的需求,最常用)

每次挂载模型时,对全局缓存的 gltf 实例做深克隆,生成完全独立的副本再使用。修改 Model 组件逻辑:

import { useMemo } from 'react'
import { clone } from 'three'
import { useGLTF } from 'drei'

const Model = ({ modelPath }) => {
  const gltf = useGLTF(modelPath, true)
  // 对缓存的原始scene做深克隆,生成独立可挂载的实例
  const clonedScene = useMemo(() => clone(gltf.scene), [gltf])
  return <primitive object={clonedScene} dispose={null} />
}
  • 注意必须用 useMemo 缓存克隆结果,不要在组件每次重渲染时都重新克隆,避免不必要的性能开销。
  • drei 内置了专门的克隆工具 useClone,可以直接调用简化代码。

2. 静态展示场景

如果不需要给每个模型做独立的动画、交互逻辑,可以直接在顶层 Suspense 内部挂载同一份模型实例,在不同的位置坐标下引用渲染,不需要在每个 ITEM 组件内部单独加载模型。这种方式由于共用同一个实例,无法给不同位置的模型绑定独立的状态控制。

3. 修正现有代码的其他潜在问题

  • 原代码中直接把 GLTF 模型塞在空 <mesh> 节点下的结构不合理:GLTF 的 scene 是独立的 Object3D 类型,不是 mesh 的子几何体,会加剧渲染异常。正确的结构应该用 <group> 作为每个 ITEM 的容器,把旋转控制的 ref 直接绑定在克隆后的模型实例上:
    const ITEM = ({ item, count }) => {
      const modelPath = '/model/scene.gltf'
      const modelRef = useRef(null)
      useFrame(() => {
        if (modelRef.current) {
          modelRef.current.rotation.y += 0.01
        }
      })
      // 用传入的count参数做位置偏移,避免所有模型重叠
      return (
        <group position={[count * 2, 0, 0]}>
          <Model modelPath={modelPath} ref={modelRef} />
        </group>
      )
    }
    
  • 原代码中所有 ITEM 的 position 都是固定的 [1,1,1],就算解决了模型挂载问题,所有模型也会完全重叠在同一个坐标点上,记得利用传入的 count 参数给不同模型设置横向/纵向偏移,避免显示重叠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 19:54:08