Three.js,在网格之间共享ShaderMaterial但具有不同的统一集

时间:2013-03-24 11:25:58

标签: three.js

正如标题所说,我想重复使用给定的ShaderMaterial用于不同的网格,但是每个网格具有不同的制服集(事实上,一些制服可能在网格之间变化,但不一定都是全部):是有可能吗?

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

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

请注意,我的问题与此Many meshes with the same geometry and material, can I change their colors?有关,但仍然不同,因为我主要关注资源的浪费 - 性能明智我不认为多重之间会有很大不同ShaderMaterial或单个,因为引擎应该足够聪明,注意所有材料都有相同的程序,不要将它们重新发送到gfx卡。

由于

2 个答案:

答案 0 :(得分:6)

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

这应该有效。

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

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

three.js r.64

答案 1 :(得分:0)

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

在较新的发行版中,另一个选择是使用单个ShaderMaterial,但要在对象的onBeforeRender函数中添加对制服的更改。这样可以避免在渲染器中不必要地调用initMaterial,但是是否要使其整体上成为更快的解决方案,则必须进行测试。如果在渲染之前过多地推送了要修改的内容,这可能是一个有风险的解决方案,因为在最坏的情况下,单个材质可能必须在渲染过程中多次重新编译。我建议this guide以获得更多提示。