5

正如标题所说,我想为不同的网格重用给定的 ShaderMaterial,但每个网格都有一组不同的制服(事实上,一些制服可能在网格之间有所不同,但不一定全部):这可能吗?

在这种情况下,必须为每个网格创建一个完整的 ShaderMaterial 对我来说似乎是一种资源浪费,其想法是拥有一个顶点/片段着色器程序,但通过不同的制服对其进行配置,其值会根据网格而改变. 如果我为每个网格创建一个新的 ShaderMaterial,我最终会得到很多重复(顶点 + 片段程序 + Material / ShaderMaterial 类的所有其他数据成员)。

如果引擎能够在绘制网格之前调用回调,我可以更改制服并实现我想要做的事情。另一种可能性是拥有一个“LiteShaderMaterial”,它将保存一个指向共享 ShaderMaterial 的指针 + 仅用于我的网格的特定制服。

请注意,我的问题与此有关许多具有相同几何形状和材料的网格,我可以更改它们的颜色吗?但仍然不同,因为我最关心资源的浪费 - 性能方面,我认为拥有多个 ShaderMaterial 或单个 ShaderMaterial 并没有太大不同,因为引擎应该足够聪明,可以注意到所有材料具有相同的程序,不要将它们重新发送到 gfx 卡。

谢谢

4

2 回答 2

8

克隆 aShaderMaterial时,通过引用复制属性和顶点/片段程序。只有制服是按价值复制的,这就是你想要的。

这应该有效地工作。

您可以通过创建一个ShaderMaterial然后使用ShaderMaterial.clone()为每个网格克隆它来向自己证明这一点。然后为每种材料分配唯一的统一值。

在控制台中输入“render.info”。它应该显示 1 个程序。

三.js r.64

于 2013-03-24T16:23:59.227 回答
1

您可以使用或其他方式安全地创建ShaderMaterial具有相同参数的多个实例。cloneThree.jsmaterial.needsUpdate最初会true为每个实例做一些额外的检查,但随后它将能够为所有实例重用相同的程序。

在较新的版本中,另一种选择是使用单个,但要在对象的函数ShaderMaterial中添加对制服的更改。onBeforeRender这避免了initMaterial在渲染器中不必要的调用,但是这是否使它成为一个整体上更快的解决方案必须进行测试。如果您在渲染之前推送太多正在修改的内容,这可能是一个有风险的解决方案,因为在最坏的情况下,单个材质可能必须在渲染期间重新编译多次。我推荐本指南以获取更多提示。

于 2019-07-29T00:46:55.270 回答