在react-三纤维/drei/Three.js中使用相同的GLTF模型两次

Rap*_*ael 7 three.js reactjs gltf react-three-fiber

在这个最小的反应三纤维应用程序中,我尝试加载并包含相同的 GLTF 模型两次:

import React, { Suspense } from "react";
import { Canvas } from "@react-three/fiber";
import { useGLTF } from "@react-three/drei";

function MyContent() {
  const firstGltf = useGLTF("/eye/scene.gltf");
  const secondGltf = useGLTF("/eye/scene.gltf");

  return (
    <>
      <primitive object={firstGltf.scene} position={[-200, 0, -400]} />
      <primitive object={secondGltf.scene} position={[200, 0, -400]} />
    </>
  );
}

export default function App() {
  return (
    <Canvas>
      <ambientLight color="white" intensity={0.5} />

      <Suspense fallback={null}>
        <MyContent />
      </Suspense>
    </Canvas>
  );
}
Run Code Online (Sandbox Code Playgroud)

请参阅此代码和框

然而,只有第二个<primitive>是可见的。如果我删除第二个<primitive>,则第一个可见。我正在努力理解为什么会发生这种情况以及如何做得更好。

(是因为第二次调用useGLTF记住"/eye/scene.gltf"已经加载并返回相同的对象吗?这是否以某种方式搞乱了 的用法<primitive>,也许是因为材料/几何图形没有被重新创建第二次并且只存在一次? )

特别是,这就是我想要实现的目标:

  • 在我的画布上多次使用 gltf 模型
  • 理想情况下,只加载一次 gltf

最重要的是,也许你也可以帮助我澄清这些问题,以便我更好地了解这里实际发生的情况:

  • 由于我只想要 3D 模型,那么这是处理对象的正确方法吗gltf.scene
  • 实际上是<primitive>显示 3D 模型的正确方法吗?或者我应该以某种方式从场景中提取几何图形/纹理并渲染它们?

谢谢你!

Mic*_*ung 6

我不是这方面的专家three.js,只是根据我的发现并尝试回答您的问题。


1. 即使定义了 2 个基元,也只显示一只眼睛

如果使用 导入相同的模型useGLTF(),它将引用相同的对象。因此,这两个原语指向相同的 gltf,并且仅应用最后/一个配置。

const firstGltf = useGLTF("/eye/scene.gltf");
const secondGltf = useGLTF("/eye/scene.gltf");
const glassesGltf = useGLTF("/glasses/scene.gltf");

// for demonstrating first eye is same as second eye
// Output: false, true
console.log(firstGltf === glassesGltf, firstGltf === secondGltf);
Run Code Online (Sandbox Code Playgroud)

2. <primitive>3D模型的展示方式实际上是正确的吗?

是的。但如果您想在屏幕上多次显示相同的 gltf,则需要创建网格并应用模型的几何形状和材质,以便您可以拥有一个新对象。

function Model(props) {
  const { nodes, materials } = useGLTF("/eye/scene.gltf");
  return (
    <group
      {...props}
      dispose={null}
      rotation={[Math.PI, 0, -Math.PI / 2]}
      scale={[1, 1, 1]}
    >
      <mesh
        geometry={nodes.Sphere001_Eye_0.geometry}
        material={materials.material}
      />
    </group>
  );
}
...
<Model position={[-1, 0, 1]} />
<Model position={[1, 0, 1]} />
Run Code Online (Sandbox Code Playgroud)

这是演示的代码和盒子


前几年:

您可以使用此库https://github.com/pmndrs/gltfjsx从模型生成 jsx。