Three.js предоставляет мощные средства для работы с материалами, которые определяют внешний вид объектов в 3D-сцене. Эффективное управление материалами позволяет уменьшить нагрузку на графический процессор, повысить производительность и облегчить организацию кода. Основными концепциями являются переиспользование материалов, клонирование и настройка параметров на лету.
В Three.js материалы представлены объектами, наследующимися от класса
THREE.Material. Наиболее часто используются:
THREE.MeshBasicMaterial — простой материал без
освещения.THREE.MeshStandardMaterial — физически корректный
материал с поддержкой PBR (Physically Based Rendering).THREE.MeshPhongMaterial — материал с бликами и
спекулярным освещением.Каждый материал содержит набор свойств: цвет (color),
текстуры (map, normalMap,
roughnessMap), прозрачность (opacity,
transparent) и отражательную способность
(metalness, roughness).
Ключевой момент: использование одного и того же объекта материала для нескольких мешей уменьшает потребление памяти, но изменяет внешний вид всех объектов, использующих этот материал.
Переиспользование позволяет экономить ресурсы, но требует понимания того, что один экземпляр материала является общим для всех объектов.
Пример:
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const cube1 = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), material);
const cube2 = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), material);
scene.add(cube1, cube2);
В этом примере оба куба используют один и тот же материал. Если изменить цвет:
material.color.set(0xff0000);
Оба куба станут красными. Это поведение нужно учитывать при динамическом изменении свойств.
Чтобы изменить свойства материала у конкретного объекта, не
затрагивая другие, используется метод clone():
const originalMaterial = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const cube1 = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), originalMaterial);
// Клонируем материал для второго куба
const clonedMaterial = originalMaterial.clone();
clonedMaterial.color.set(0xff0000);
const cube2 = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), clonedMaterial);
scene.add(cube1, cube2);
Клонирование создаёт новый объект материала с теми же параметрами, что и оригинал, но изменения в клоне не влияют на оригинал.
Важно: при клонировании текстур (map,
normalMap) ссылки на текстуры остаются общими, то есть
текстуры не копируются. Это позволяет экономить видеопамять, но
изменение самой текстуры отразится на всех материалах, которые её
используют.
clone) —
копирует все свойства объекта, но ссылки на вложенные объекты, такие как
текстуры, остаются общими.const deepClone = originalMaterial.clone();
if (originalMaterial.map) {
deepClone.map = originalMaterial.map.clone();
}
Такой подход необходим, если требуется независимая модификация текстур для каждого экземпляра материала.
Для сложных объектов с множеством поверхностей
(geometry.groups) можно использовать массивы материалов.
Каждая группа может иметь свой материал, и массив можно клонировать
целиком:
const materials = [
new THREE.MeshStandardMaterial({ color: 0xff0000 }),
new THREE.MeshStandardMaterial({ color: 0x00ff00 })
];
const geometry = new THREE.BoxGeometry(1, 1, 1);
geometry.clearGroups();
geometry.addGroup(0, 6, 0); // грань 1 — материал 0
geometry.addGroup(6, 6, 1); // грань 2 — материал 1
const mesh = new THREE.Mesh(geometry, materials);
scene.add(mesh);
Клонирование массива материалов позволяет создавать новые комбинации для других объектов без влияния на оригинальные материалы:
const clonedMaterials = materials.map(mat => mat.clone());
Three.js позволяет изменять свойства материалов в процессе работы сцены. Для того чтобы изменения отображались корректно, необходимо помечать материал как требующий обновления:
material.color.set(0x0000ff);
material.needsUpdate = true;
needsUpdate сообщает рендереру, что шейдеры или
параметры материала изменились, и требуется пересоздание GPU-ресурсов.
Без этого свойство может не обновиться на экране.
needsUpdate: после
изменения параметров материалов обязательно устанавливать этот флаг,
особенно при динамическом изменении цвета, карт или шейдеров.Эффективное управление материалами — основа оптимизации 3D-сцен в Three.js. Понимание различий между переиспользованием, клонированием и глубоким копированием текстур позволяет создавать гибкие и производительные сцены, минимизируя потребление памяти и обеспечивая контроль над визуальными свойствами объектов.