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

React Three Fiber中primitive标签复用同一模型为何仅第二个生效?

问题原因与解决方案

你遇到的问题不是primitive标签只能用一次,而是Three.js中同一个Object3D对象(比如你的model.scene)无法同时挂载到多个父节点下。当你第二次用primitive添加同一个scene对象时,它会被自动从第一个primitive的父节点中移除,导致第一个primitive没有可显示的内容。

另外你虽然调用了两次useGLTF,但useGLTF默认会缓存加载结果,所以model和model2其实指向的是同一个模型实例,并不是两个独立的副本。

解决方法

1. 克隆模型实例(推荐)

只加载一次模型,然后通过clone()方法创建独立的副本,这样就能同时渲染多个相同模型,还能避免重复请求资源:

import { useGLTF, OrbitControls, useHelper, useScroll, Html } from '@react-three/drei'
import * as THREE from 'three'
import { useFrame } from '@react-three/fiber'
import { useRef, forwardRef, useMemo } from 'react'

export default function App() {
    // 仅加载一次模型
    const model = useGLTF('/iphone_14_pro_max.glb');
    // 深克隆模型场景,确保材质、几何体都是独立引用
    const modelSceneClone = useMemo(() => model.scene.clone(true), [model])

    const scroll = useScroll()
    const iphone = useRef()
    const first = useRef()

    useFrame((state, delta) => {
        const r1 = scroll.range(0 / 4, 1 / 4)
        const r2 = scroll.range(1 / 4, 1 / 4)
        const r3 = scroll.range(1 / 4, 1 / 4)

        iphone.current.rotation.y = (Math.PI * 0.67) + r1 + r2 + r3 * 3
    })

    return(
        <>
            <directionalLight position={ [ 1, 2, 3 ] } intensity={ 1.5 } />
            <ambientLight intensity={ 0.5 } />

            <primitive ref={iphone} object={model.scene} scale={20} position={ [ 0, -1.5, 0] }>
                <Tagline ref={first} left="PRO" right="BEYOND"></Tagline>
            </primitive>

            {/* 使用克隆后的独立场景实例 */}
            <primitive object={modelSceneClone} scale={15} position={ [ 1, 1, 1] } rotation-y={-45}/> 
        </>
    )
}

const Tagline = forwardRef(({ left, right, ...props }, ref) => {
    return (
      <Html occlude ref={ref} className="homepage" center {...props}>
        <h1>{left}</h1>
        <h1>{right}</h1>
      </Html>
    )
})

2. 禁用useGLTF缓存(不推荐)

如果一定要多次调用useGLTF,可以通过第二个参数禁用缓存,强制加载多个独立实例,但这样会重复请求模型文件,浪费带宽和性能:

const model = useGLTF('/iphone_14_pro_max.glb', { cache: false });
const model2 = useGLTF('/iphone_14_pro_max.glb', { cache: false });

关键说明

  • .clone(true)是深克隆,会复制模型的所有子对象、材质和几何体,确保每个副本都是独立的,不会互相影响状态。
  • 优先使用克隆方式,既保证功能又能优化性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 02:50:33