我有大量(〜1000)个THREE.Mesh
对象,它们是由相同的THREE.Geometry
和THREE.MeshPhongMaterial
(有一个映射)构造的。
我想分别对这些对象进行着色(着色)。
天真,我尝试更改mesh.material.color
属性,但是在任何对象上更改此属性都会一次更改所有对象的颜色。这是有道理的,因为所有对象之间仅共享一种材料。
我的下一个想法是为每个对象创建一个单独的THREE.MeshPhongMaterial
。因此,现在我有大量由相同的THREE.Mesh
构造的THREE.Geometry
对象,但有单独的THREE.MeshPhongMaterials
(共享相同的纹理)。这使我可以单独更改颜色,但是性能较差。 chrome配置文件显示该应用程序在处理诸如切换纹理之类的材质上花费了大量时间。
材质颜色在着色器中只是均匀的。因此,更新该制服应该很快。
问题:是否可以从网格级别覆盖材质颜色?
[如果有的话,我相信我可以在所有对象之间共享材料并恢复我的表现,同时仍然可以单独更改颜色。
[[我在v49和v54上进行了测试,它们具有相同的性能和降级性能]
update:我已经建立了一个测试用例,由于这个原因导致的性能下降比我原先认为的要小,但是仍然可以测量。
这里有两个链接:
在第一种情况下,只有两种材料,在第二种情况下,每个立方体都有其自己的材料。我在这台机器上测得第一种情况的帧率为53fps,第二种情况的帧率为46fps。这大约下降了15%。
[在两种情况下,每个立方体的材质的颜色每帧都会改变。对于许多材料,实际上我们看到每个立方体都有自己的颜色,对于只有两种材料的情况,我们看到它们都具有相同的颜色(与预期相同)。
是。对于每个对象,使用material.clone()
克隆材质,修改其emissive
和color
,然后将对象的材质设置为此克隆。着色器和属性是通过引用复制的,因此不必担心每次都克隆整个材质。实际上,按值复制的唯一东西是制服(例如emissive
和color
)。因此,您可以针对每个对象更改它们。
我个人将原始材料存储在对象的单独的自定义属性上,以便以后可以轻松切换回它;取决于您的需求。
如果您正在编写自己的着色器,则可以将uniform
变量用于常规色度(而不是特定于顶点),然后将其传递给着色器以分解为整体颜色。 vec4f_t
和vec4f()
在C部分中不是标准的,但是您的代码可能已经具有等效项。
C:
vec4f_t hue = vec4f(....); // fill in as desired
// load the shader so that GLuint shader_id is available.
// "hue" is a uniform var in the vertexshader
GLUint hue_id = glGetUniformLocation(shader_id, "hue");
// later, before rendering the object:
glUniform4fv(hue_id, 1, &hue);
the.vertexshader:
uniform vec4 hue; // add this and use it in the texture's color computation