首页 文章

许多具有相同几何和材质的网格,我可以改变它们的颜色吗?

提问于
浏览
17

我有大量(~1000) THREE.Mesh 个对象,它们是由相同的 THREE.GeometryTHREE.MeshPhongMaterial (有一个 Map )构建的 .

我想单独为这些物体着色(着色) .

天真地,我尝试更改 mesh.material.color 属性,但是在任何对象上更改此属性会立即更改所有对象的颜色 . 这是有道理的,因为在所有对象之间只共享一种材料 .

我的下一个想法是为每个对象创建一个单独的 THREE.MeshPhongMaterial . 所以,现在我有大量的 THREE.Mesh 对象是由相同的 THREE.Geometry 构建的,但是具有单独的 THREE.MeshPhongMaterials (它们具有相同的纹理) . 这允许我单独更改颜色,但性能更差 . Chrome配置文件显示应用程序花费大量时间进行物理操作,如切换纹理 .

着色器中的材质颜色只是一个统一的颜色 . 所以,更新那件制服应该很快 .

question: 有没有办法从网格级别覆盖材质颜色?

如果有,我相信我可以在我的所有物品中分享材料并恢复我的表现,同时仍然单独改变颜色 .

[我在v49和v54上进行了测试,它们具有相同的性能和降级]

update: 我已经构建了一个测试用例,由此引起的性能下降比我想象的要小,但仍然是可测量的 .

这里有两个链接:

在第一种情况下,只有两种材料,在第二种情况下,每个立方体都有自己的材料 . 我在这台机器上测量第一种情况的帧率为53fps,第二种情况的帧率为46fps . 这大约下降了15% .

在这两种情况下,每个立方体的材料颜色都会改变 . 在有许多材料的情况下,我们实际上看到每个立方体都有它自己的颜色,在只有两种材料的情况下,我们看到它们都具有相同的颜色(如预期的那样) .

2 回答

  • 0

    如果您正在编写自己的着色器,则可以使用 uniform 变量作为一般色调(不是特定于顶点)并将其传递到着色器以分解为整体颜色 . vec4f_tvec4f() 在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
    
  • 3

    是 . 对于每个对象,使用 material.clone() 克隆您的材质,修改其 emissivecolor ,并将对象的材质设置为此克隆 . 着色器和属性通过引用复制,因此不必担心每次都要克隆整个材质;事实上,唯一被 Value 复制的东西是制服(例如 emissivecolor ) . 所以你可以根据每个对象更改这些内容 .

    我个人将原始材料存储在对象的单独自定义属性中,以便我以后可以轻松切换回它;取决于你的需求 .

相关问题