可编程更改gltf进口网格材料-反应三纤维



我目前正在做一个react-three-fiber项目。我已经用useGLTF从@react-three/drei导入了模型。

const { nodes, materials } = useGLTF('/model.glb');

我访问glb文件中的材料。为了访问和操作模型,我使用gltfjsx来生成模型。

现在我需要改变一个网格的材料编程。因为我不能直接访问模型的JSX,所以我使用React.cloneElement并修改网格的道具。

所以我尝试这样做:

return React.cloneElement(mesh, {
material: overwriteMaterial ?
<meshStandardMaterial attach="material" color={0xa3005c} metalness={1} roughness={0.2} visible={true} /> :
materials['mat_7']
});

如果overwriteMaterial为假,则工作。它显示了它应该显示的材料。但如果为真,则网格消失。

我还想把<meshStandardMaterial />在网格的儿童道具。像这样:

return React.cloneElement(mesh, {
material: overwriteMaterial ? undefined : materials['mat_7'],
children: overwriteMaterial ? <meshStandardMaterial attach="material" color={0xa3005c} metalness={1} roughness={0.2} visible={true} /> : undefined
});

有了这个,我总是得到这个错误,我不知道为什么它出现:

TypeError: Cannot read properties of undefined (reading 'visible')

这种方法是否可行,还是我做了完全错误的事情?

欢迎大家的帮助。由于

好吧,我自己找了几个小时的答案。

material属性不接受jsx标签。所以,如果你创建一个MeshStandardMaterial类的实例,你可以把它传递给属性,它工作得很好。现在它看起来像这样:

return React.cloneElement(mesh, {
material: overwriteMaterial
? new MeshStandardMaterial({ color: 0x0ff000 })
: materials['mat_7']
})

注意:类MeshStandardMaterial是从three包导出的。

我真的不认为你必须克隆任何反应元素,这似乎是不正确的。你可以克隆或改变材料,就像你在一个普通的三个应用程序。我不知道为什么你甚至想克隆jsx。

const { scene } = useGLTF(url)
const clonedScene = useMemo(() => scene.clone(), [])
useLayoutEffect(() => {
clonedScene.traverse(o => {
if (o.type === 'Mesh') {
o.material = ...
}
})
}, [clonedScene]}
return <primitive object={clonedScene} />

你也可以完全跳过clonedScene,这只有当你计划在你的场景中多次重复使用模型时。

最新更新