Группы геометрии и многоматериальные меши

Three.js предоставляет гибкие инструменты для работы с несколькими объектами сцены одновременно. Одним из ключевых подходов является использование групп (THREE.Group). Группа позволяет объединять несколько мешей или других объектов в единый контейнер, сохраняя их индивидуальные трансформации, но позволяя манипулировать всей группой как единым объектом.

const group = new THREE.Group();

const geometry1 = new THREE.BoxGeometry(1, 1, 1);
const material1 = new THREE.MeshStandardMaterial({ color: 0xff0000 });
const cube1 = new THREE.Mesh(geometry1, material1);

const geometry2 = new THREE.SphereGeometry(0.5, 32, 32);
const material2 = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const sphere = new THREE.Mesh(geometry2, material2);
sphere.position.set(2, 0, 0);

group.add(cube1);
group.add(sphere);

scene.add(group);

Ключевые моменты при работе с группами:

  • Трансформации группы применяются ко всем дочерним объектам. Поворот, масштаб или позиция группы автоматически влияют на все её элементы.
  • Индивидуальные трансформации объектов сохраняются. Поворот одного меша в группе будет комбинироваться с трансформацией группы.
  • Группы могут быть вложенными. Можно создавать сложные сцены с иерархией объектов, где каждый уровень имеет собственные трансформации.

Использование многоматериальных мешей

В Three.js объект THREE.Mesh может иметь один материал для всей геометрии, но при необходимости возможно назначение нескольких материалов для разных частей геометрии. Для этого используется массив материалов и индексные группы (geometry.groups).

const geometry = new THREE.BoxGeometry(2, 2, 2);

// Определение двух материалов
const materials = [
    new THREE.MeshStandardMaterial({ color: 0x0000ff }),
    new THREE.MeshStandardMaterial({ color: 0xffff00 })
];

// Настройка групп граней
geometry.clearGroups();
geometry.addGroup(0, 6, 0);  // первые 6 вершин -> первый материал
geometry.addGroup(6, 30, 1); // оставшиеся вершины -> второй материал

const multiMaterialMesh = new THREE.Mesh(geometry, materials);
scene.add(multiMaterialMesh);

Принципы работы с многоматериальными мешами:

  • Геометрические группы задаются через geometry.addGroup(startIndex, count, materialIndex), где startIndex — индекс вершины, count — количество вершин, materialIndex — индекс материала в массиве.
  • Материалы должны быть совместимы с типом геометрии. Для стандартной геометрии лучше использовать MeshStandardMaterial или MeshPhongMaterial.
  • Многоматериальные меши позволяют создавать сложные объекты без разбиения на несколько отдельных мешей, что оптимизирует производительность и упрощает управление сценой.

Комбинирование групп и многоматериальных мешей

Для крупных сцен удобно объединять возможности групп и многоматериальных мешей. Например, можно создать сложный объект с различными материалами и поместить его в группу с другими объектами для удобного управления:

const mainGroup = new THREE.Group();

const boxGeometry = new THREE.BoxGeometry(1, 1, 1);
const materials = [
    new THREE.MeshStandardMaterial({ color: 0xff00ff }),
    new THREE.MeshStandardMaterial({ color: 0x00ffff })
];
boxGeometry.clearGroups();
boxGeometry.addGroup(0, 6, 0);
boxGeometry.addGroup(6, 30, 1);

const multiBox = new THREE.Mesh(boxGeometry, materials);
multiBox.position.set(0, 0, 0);

const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32);
const sphereMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff });
const sphereMesh = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphereMesh.position.set(2, 0, 0);

mainGroup.add(multiBox);
mainGroup.add(sphereMesh);
scene.add(mainGroup);

Преимущества комбинирования:

  • Упрощение управления сложными объектами сцены.
  • Возможность создавать анимации и трансформации для всей группы вместо отдельных элементов.
  • Снижение количества объектов в сцене, что повышает производительность рендеринга.

Динамическое обновление материалов и геометрии

Three.js позволяет менять материалы и геометрию после создания меша:

  • mesh.material = newMaterial — смена одного материала.
  • Для многоматериальных мешей можно менять массив материалов mesh.material[index].
  • Геометрические группы можно пересоздавать, очищая geometry.groups и добавляя новые через addGroup.
multiBox.material[1].color.set(0xffaa00);
boxGeometry.clearGroups();
boxGeometry.addGroup(0, 12, 0);
boxGeometry.addGroup(12, 24, 1);

Это особенно важно для интерактивных сцен, где объекты должны изменять внешний вид в зависимости от действий пользователя или логики приложения.

Оптимизация и рекомендации

  • Использовать группы для объектов, которые всегда будут перемещаться или вращаться вместе.
  • Многоматериальные меши эффективны для объектов, которые разделяются визуально, но не требуют отдельного управления как отдельные меши.
  • Для сложных сцен избегать слишком большого числа отдельных мешей; лучше объединять объекты в группы или использовать InstancedMesh, если объекты идентичны.

Группы и многоматериальные меши формируют основу гибкой и масштабируемой архитектуры сцен в Three.js, позволяя управлять визуальными объектами эффективно и с высокой степенью контроля над трансформациями и материалами.