当前位置: 首页 > 知识库问答 >
问题:

以编程方式更改gltf导入网格的材质-反应三种纤维

云何平
2023-03-14

我目前在react three fiber的一个项目中工作。我已经从@react three/drei导入了带有useGLTF的模型。

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

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

现在我需要以编程方式更改网格的材质。因为我不能直接访问模型的JSX,所以我用React.clone元素来修改网格的道具。

所以我尝试了这样的方法:

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

如果overwriteMaterial为false,则该选项有效。它显示了它应该使用的材质。但如果这是真的,网格就会消失。

我还想到了把

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
});

有了这个,我总是会出现这样的错误,我不知道为什么会出现这样的错误:

无法读取未定义的属性(读取可见)

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

欢迎每一个帮助。谢啦


共有2个答案

羊舌富
2023-03-14

我真的不认为必须克隆任何react元素,这似乎不正确。你可以像在普通的三个应用程序中一样克隆或变异材料。我不知道你为什么要克隆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,只有在计划在场景中多次重复使用模型时才可以这样做。

姬俊远
2023-03-14

好的,我自己找到了答案,经过几个小时的寻找解决方案。

材质属性不接受JSX标记。因此,如果您创建类的实例Mesh标准材料,您可以将其传递给属性,并且它工作得非常好。现在它看起来像这样:

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

注意:类MeshStandard ard材料是从包导出的。

 类似资料:
  • 我试图在一个简单的react三纤维场景中动态更改“.gltf”模型的纹理贴图值。如果我理解正确,您必须在材质上添加纹理文件,然后将材质添加到模型中?在我的场景中,纹理文件被烘焙到“.gltf”文件中。我想用jsx更改alphaMap的不透明度等值。 这是我的沙箱:https://codesandbox.io/s/patient-framework-3holn?file=/src/App.js 我知

  • 我已成功地将gltf对象加载到我的react three fiber场景中。现在,我想将材质附着到模型。在这个模型上可以使用标准材料吗?以下是我尝试过的: 常量形状=(道具)=

  • 谢谢你花时间看我的问题。 我用的是三根纤维。我试图将小盒子连接到网格的两侧。我从光线投射器获得了长方体网格的位置。 我的问题是,在旋转父组后,t恤网格的矩阵似乎是反向的。据我所知,光线投射器是基于这个矩阵工作的。我确实尝试过updateMatrix()和updateMatrix World(),但结果令人困惑。 在这样旋转组之后,更新子矩阵的标准方法是什么?任何帮助都将不胜感激。 这是我问题的一个

  • 我已经尝试了这个解决方案,并且在XML中工作得很好,但是我如何通过代码来做同样的事情呢? 事实上,我想改变编辑文本(主题:标签,文本颜色,行颜色)按一个按钮。

  • 问题内容: 我有一个带有标题的导航栏。当我双击文本以将其重命名时,它实际上说这是一个导航项,所以可能就是这样。 我正在尝试使用代码来更改文本,例如: 那显然不是我的代码,只是显示了它是如何工作的。 因此,每当我按下按钮时,我都希望标题更改。 问题答案: 您可以通过更改显示的视图控制器的标题来更改标题: 通常,这是在视图控制器上加载视图时完成的: 但是,这仅在将视图控制器嵌入UINavigation

  • 我从一个网站下载了一组文件,并在blender中导出了glb、gltf和mtl文件。我可以让glb或gltf文件显示在反应三纤维场景,但我不知道如何让纹理显示正确。我遇到了几个演示,但它们看起来很旧,什么不起作用。 下面是我如何加载文件。