Много ячеек с той же геометрией и материалом, могу ли я изменить их цвета?
У меня есть большое количество (~ 1000) объектов THREE.Mesh
, которые были построены из тех же THREE.Geometry
и THREE.MeshPhongMaterial
(которые имеют карту).
Я хотел бы покрасить эти объекты индивидуально.
Naïvely, я попытался изменить свойство mesh.material.color
, но изменение этого свойства на любом из объектов сразу меняет цвет всех объектов. Это имеет смысл, поскольку есть только один материал, который разделяется между всеми объектами.
Моя следующая идея заключалась в создании отдельного THREE.MeshPhongMaterial
для каждого объекта. Итак, теперь у меня есть большое количество объектов THREE.Mesh
, которые были построены из одного и того же THREE.Geometry
, но имеют индивидуальные THREE.MeshPhongMaterials
(которые имеют одну и ту же текстуру). Это позволяет мне менять цвета по отдельности, но производительность хуже. Хром-профилист показывает, что приложение тратит значительное время на материальные вещи, такие как переключение текстур.
Цвет материала является однородным в шейдере. Итак, обновление этой униформы должно быть довольно быстрым.
вопрос: Есть ли способ переопределить цвет материала с уровня сетки?
Если бы это было, я считаю, что могу поделиться материалом среди всех своих объектов и вернуть свою производительность, сохраняя при этом индивидуальные цвета.
[Я тестировал на v49 и v54, они имеют одинаковую производительность и деградацию]
update: Я построил тестовый пример, и падение производительности из-за этого меньше, чем я думал, но это все еще измеримо.
Вот две ссылки:
В первом случае есть только два материала, во втором случае каждый куб имеет свой собственный материал. Я измеряю частоту кадров первого случая как 53fps на этой машине, а частота кадров второго составляет 46 кадров в секунду. Это примерно на 15% меньше.
В обоих случаях цвет материала каждого куба изменяется каждый кадр. В случае со многими материалами мы фактически видим, что каждый куб получает свой собственный цвет, в случае только с двумя материалами мы видим, что все они имеют один и тот же цвет (как и ожидалось).
Ответы
Ответ 1
Да. Для объекта клонируйте свой материал с помощью material.clone()
, измените его emissive
и color
и установите материал объекта в этот клон. Шейдеры и атрибуты копируются по ссылке, поэтому не беспокойтесь, что каждый раз клонирование всего материала; на самом деле единственными вещами, которые копируются по значению, являются униформы (такие как emissive
и color
). Таким образом, вы можете изменить их для каждого отдельного объекта.
Лично я храню исходный материал на отдельном, настраиваемом свойстве объекта, чтобы я мог легко вернуться к нему позже; зависит от ваших потребностей.
Ответ 2
Если вы пишете свои собственные шейдеры, вы можете использовать переменную uniform
для общего оттенка (не специфичного для вершины) и передать это в шейдер для факторинга в общий цвет. vec4f_t
и vec4f()
не являются стандартными в части 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 color computation