Меш: геометрия плюс материал

Любой видимый объект в Three.js — это меш. Разбираем его на две понятные части.

Mesh — это видимый объект сцены, состоящий из двух частей: геометрии (форма — где вершины и грани) и материала (внешний вид — цвет, блеск, реакция на свет).

Форма и облик — отдельно

Three.js намеренно разделяет «какой формы объект» и «как он выглядит». Это удобно: одну и ту же сферическую геометрию можно покрасить в красный матовый материал или в зеркальный металл — форма не меняется, меняется только материал. И наоборот: один материал можно надеть на куб, сферу и тор.

// геометрия — форма
const geometry = new THREE.SphereGeometry(1, 32, 16);

// материал — внешний вид
const material = new THREE.MeshStandardMaterial({ color: 0xff6644 });

// меш — собранный видимый объект
const ball = new THREE.Mesh(geometry, material);
scene.add(ball);

Что внутри геометрии

Геометрия — это набор вершин (точек в пространстве) и описание, как они соединяются в треугольники (грани). GPU умеет рисовать только треугольники, поэтому любая форма — куб, сфера, модель дракона — внутри состоит из множества треугольников. Чем их больше, тем плавнее форма, но тем тяжелее рендер.

Переиспользование — важная привычка

Если вам нужно сто одинаковых кубиков, не создавайте сто геометрий и сто материалов. Создайте по одной штуке и переиспользуйте — каждый меш может ссылаться на общие geometry и material.

const geo = new THREE.BoxGeometry(1, 1, 1);
const mat = new THREE.MeshStandardMaterial({ color: 0x44aa88 });

for (let i = 0; i < 100; i++) {
  const box = new THREE.Mesh(geo, mat); // общие geo и mat
  box.position.x = i - 50;
  scene.add(box);
}

Прикинем экономию памяти на простой модели. Пусть одна геометрия куба условно «весит» 1 единицу данных, а на сцене 100 кубов.

const count = 100;
const geoCostEach = 1; // условный «вес» одной геометрии

const naive = count * geoCostEach;   // каждому свой экземпляр
const shared = 1 * geoCostEach;      // одна общая геометрия

console.log('Без переиспользования:', naive, 'ед.');
console.log('С переиспользованием:', shared, 'ед.');
console.log('Экономия в', (naive / shared) + ' раз');

Вывод:

Без переиспользования: 100 ед.
С переиспользованием: 1 ед.
Экономия в 100 раз

Итог

  • Mesh = Geometry (форма) + Material (внешний вид).
  • Любая форма внутри — треугольники; больше треугольников = плавнее, но тяжелее.
  • Переиспользуйте geometry и material для одинаковых объектов — экономит память.
Проверьте себя
1. Из каких двух частей состоит Mesh?
AИз камеры и света
BИз геометрии (форма) и материала (внешний вид)
CИз сцены и рендерера
DИз текстуры и тени
2. Что хранит геометрия?
AЦвет и блеск поверхности
BВершины, рёбра и грани — то есть форму объекта
CПоложение камеры
DСписок источников света
3. Зачем переиспользовать одну геометрию и материал для многих мешей?
AТак требует синтаксис
BЭто экономит память и ускоряет рендер — не нужно дублировать одинаковые данные
CИначе объекты будут невидимы
DЧтобы поменять цвет фона
Поддержать проект