【问题标题】:How to load the same gltf model in threejs or react-three-fiber如何在threejs或react-three-fiber中加载相同的gltf模型
【发布时间】:2021-12-08 01:04:06
【问题描述】:

我正在使用 react-three-fiber,我想建一所房子。所以我使用 GLTF 模型来显示门。

渲染一扇门很好,但是当我从同一个 GLTF 文件渲染两扇门时,只会渲染第二扇门。看起来第二扇门取代了第一扇门,而不是一扇新门。

如何实现拥有多个门,我已经搜索过,但似乎没有人问这个问题???

我的代码:

Door.tsx

import React from 'react';
import { useLoader } from "@react-three/fiber";
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';

interface DoorProps {
  rotation: any;
}

function Door(props: DoorProps) {
  const gltf = useLoader(GLTFLoader, '/simple_door.gltf');

  return (
    <>
      <primitive
        object={gltf.scene}
        position={[25, 1, -17]}
        scale={0.05}
        rotation={props.rotation}
      />
    </>
  );
}

export default Door;

Room.tsx

function Room() {
  return (
    <Canvas
      shadows
      dpr={[1, 2]}
      frameloop="demand"
      style={{ height: 800 }}
      camera={{ fov: 75, near: 0.1, far: 1000, position: [0, 10, 20] }}
    >
      <OrbitControls addEventListener={undefined} hasEventListener={undefined} removeEventListener={undefined} dispatchEvent={undefined} />
      <ambientLight intensity={0.8} />
      <color attach="background" args={['#d0d0d0']} />
      <fog attach="fog" args={['#d0d0d0', 100, 600]} />
      <Suspense fallback={null}>
        <Environment preset="city" />
        <Door />
        <Plane 
          width={50}
          height={10}
          depth={1}
          position={[0, 0, -20]}
        />
        <Door
          rotation={[0, 90*Math.PI/180, 0]}
        />

        <Plane 
          width={50}
          height={1}
          depth={50}
          position={[0, -4.5, 5]}
        />
      </Suspense>
    </Canvas>
  );
};

export default Room;

【问题讨论】:

    标签: reactjs three.js gltf react-three-fiber


    【解决方案1】:

    您似乎正在尝试克隆您的 3D 门模型,

    有几种方法可以做到这一点,您正在寻找的可能是对克隆功能的简单使用:

    import React from 'react';
    import { useGraph } from '@react-three/fiber'
    import { useGLTF } from '@react-three/drei'
    import { SkeletonUtils } from "three/examples/jsm/utils/SkeletonUtils"
    
    interface DoorProps {
      rotation: any;
    }
    
    function Door(props: DoorProps) {
      const { scene, materials, animations } = useGLTF('/simple_door.gltf');
      const clone = useMemo(() => SkeletonUtils.clone(scene), [scene])
      const { nodes } = useGraph(clone)
    
      return (
        <>
          <primitive
            object={nodes}
            position={[25, 1, -17]}
            scale={0.05}
            rotation={props.rotation}
          />
        </>
      );
    }
    
    export default Door;
    

    我使用了 drei 包,因为它有助于在需要时加载模型以外的其他信息

    这是另一个例子: https://codesandbox.io/s/react-three-fiber-wildlife-nrbnq?file=/src/Model.js

    您可能还想显示很多门,在这种情况下,我建议您使用 instancedMesh 而不是原始的

    还有一个可以帮助您创建 Door 组件的工具是 gltfjsx,看看它: https://www.npmjs.com/package/gltfjsx

    【讨论】:

      【解决方案2】:

      你不能在两个地方添加相同的模型,threejs 会从第一个地方自动卸载它。解决方案是gltfjsx。这就是允许您重用模型的原因。香草三中没有对应的,它们通常重新解析和/或克隆。使用 gltfjsx 模型只加载和解析一次,但由于它是不可变的,因此您可以轻松地重新使用它 ootb。

      这里有一个例子:https://codesandbox.io/s/re-using-gltfs-dix1ygltfjsx 甚至可以生成实例,所以无论你渲染多少次,你都只有一个 drawcall。

      【讨论】:

        【解决方案3】:

        你没有通过rotation第一道门的道具,

        如果您不想将 rotation 属性传递给 First Door,请将旋转设置为像这样的可选属性。

        interface DoorProps {
           rotation?: any;
        }
        

        【讨论】:

        • 好的,谢谢。但是我试过了,我仍然只能看到第二扇门,第一扇没有旋转的门没有渲染。
        猜你喜欢
        • 2021-10-19
        • 2021-11-12
        • 2021-04-16
        • 2020-11-09
        • 2021-03-05
        • 1970-01-01
        • 2020-11-08
        • 2021-04-05
        • 2020-07-30
        相关资源
        最近更新 更多