Har*_*old 18 performance share colors material three.js
我有大量(〜1000)THREE.Mesh已经从同一构造的对象THREE.Geometry和THREE.MeshPhongMaterial(其具有地图).
我想单独着色(着色)这些对象.
天真地,我尝试更改mesh.material.color属性,但是在任何对象上更改此属性会立即更改所有对象的颜色.这是有道理的,因为在所有对象之间只共享一种材料.
我的下一个想法是THREE.MeshPhongMaterial为每个对象创建一个单独的.所以,现在我有大量的THREE.Mesh对象是由相同的构造THREE.Geometry,但有个体THREE.MeshPhongMaterials(共享相同的纹理).这允许我单独更改颜色,但性能更差.Chrome配置文件显示应用程序花费大量时间进行物理操作,例如切换纹理.
材质颜色在着色器中只是一个统一的颜色.所以,更新那件制服应该很快.
问题:有没有办法从网格级别覆盖材质颜色?
如果有,我相信我可以在我的所有物品中分享材料并恢复我的表现,同时仍然单独改变颜色.
[我在v49和v54上测试过,它们具有相同的性能和降级]
更新:我已经构建了一个测试用例,由此产生的性能下降比我想象的要小,但仍然是可测量的.
这是两个链接:
在第一种情况下,只有两种材料,在第二种情况下,每个立方体都有自己的材料.我在这台机器上测量第一种情况的帧率为53fps,第二种情况的帧率为46fps.这大约下降了15%.
在这两种情况下,每个立方体的材料颜色都会发生变化.在有许多材料的情况下,我们实际上看到每个立方体都有它自己的颜色,在只有两种材料的情况下,我们看到它们都具有相同的颜色(如预期的那样).
是的。每个对象,使用 克隆您的材质material.clone(),修改其emissive和color,并将对象的材质设置为此克隆。着色器和属性是通过引用复制的,所以不用担心每次都克隆整个材质;实际上,按值复制的唯一内容是制服(例如emissiveand 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);
Run Code Online (Sandbox Code Playgroud)
the.vertexshader:
uniform vec4 hue; // add this and use it in the texture's color computation
Run Code Online (Sandbox Code Playgroud)