我有大量(~1000)个THREE.Mesh
个对象,这些对象是使用相同的THREE.Geometry
和THREE.MeshPhongMaterial
(有地图)构建的。
我想单独为这些对象着色(着色)。
Naïvely,我尝试更改mesh.material.color
属性,但是在任何对象上更改此属性会立即更改所有对象的颜色。这是有道理的,因为只有一种材料在所有对象之间共享。
我的下一个想法是为每个对象创建一个单独的THREE.MeshPhongMaterial
。所以,现在我有大量THREE.Mesh
个对象,这些对象是从同一个THREE.Geometry
构建的,但是具有单独的THREE.MeshPhongMaterials
(共享相同的纹理)。这允许我单独更改颜色,但性能更差。 Chrome配置文件显示应用程序花费大量时间进行物理操作,例如切换纹理。
着色器中的材质颜色只是一个统一的颜色。所以,更新那件制服应该很快。
问题:有没有办法从网格级别覆盖材质颜色?
如果有,我相信我可以在我的所有物品中分享材料并恢复表现,同时仍然单独改变颜色。
[我已经在v49和v54上进行了测试,它们具有相同的性能和降级]
更新:我已经构建了一个测试用例,因此导致的性能下降比我想象的要小,但仍然可以测量。
以下是两个链接:
在第一种情况下,只有两种材料,在第二种情况下,每个立方体都有自己的材料。我在这台机器上测量第一种情况的帧率为53fps,第二种情况的帧率为46fps。这大约下降了15%。
在这两种情况下,每个立方体的材质颜色都会改变。在使用许多材料的情况下,我们实际上看到每个立方体都有它自己的颜色,在只有两种材料的情况下,我们看到它们都具有相同的颜色(如预期的那样)。
答案 0 :(得分:3)
是。对于每个对象,使用material.clone()
克隆您的素材,修改其emissive
和color
,并将对象的材质设置为此克隆。着色器和属性通过引用复制,因此不必担心每次都要克隆整个材质;事实上,唯一被价值复制的东西是制服(例如emissive
和color
)。因此,您可以根据每个对象更改这些内容。
我个人将原始材料存储在对象的单独自定义属性中,以便我以后可以轻松切换回它;取决于你的需求。
答案 1 :(得分:0)
如果您正在编写自己的着色器,则可以使用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