如何在threejs或react-three-fiber中加载相同的gltf模型
Posted
技术标签:
【中文标题】如何在threejs或react-three-fiber中加载相同的gltf模型【英文标题】:How to load the same gltf model in threejs or react-three-fiber 【发布时间】: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;
【问题讨论】:
【参考方案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;
【讨论】:
好的,谢谢。但是我试过了,我仍然只能看到第二扇门,第一扇没有旋转的门没有渲染。以上是关于如何在threejs或react-three-fiber中加载相同的gltf模型的主要内容,如果未能解决你的问题,请参考以下文章