В 3D-графике UV-развёртка представляет собой процесс
проекции поверхности 3D-модели на двумерную плоскость для корректного
отображения текстур. Каждая вершина модели получает свои
UV-координаты (u, v), где u и
v находятся в диапазоне от 0 до 1, соответствуя
горизонтальной и вертикальной координатам текстуры.
В Three.js текстурные координаты используются в
материалах через свойство geometry.attributes.uv. Для
большинства стандартных геометрий (BoxGeometry,
SphereGeometry, PlaneGeometry) UV-координаты
генерируются автоматически. Для кастомных геометрий необходимо задавать
их вручную.
const geometry = new THREE.BoxGeometry(1, 1, 1);
console.log(geometry.attributes.uv.array); // вывод массива UV-координат
Маппинг — процесс сопоставления пикселей текстуры с полигонами модели. Three.js поддерживает несколько типов маппинга:
uv для текстуры.Для материалов MeshBasicMaterial,
MeshStandardMaterial и подобных текстура задаётся через
свойство map:
const texture = new THREE.TextureLoader().load('texture.jpg');
const material = new THREE.MeshStandardMaterial({ map: texture });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
UV-координаты определяют, какая область текстуры попадёт на
конкретный полигон. Например, u=0, v=0 соответствует левому
нижнему углу текстуры, а u=1, v=1 — правому верхнему.
Для сложных моделей часто необходимо редактировать UV-развёртку вручную. В Three.js можно использовать следующие подходы:
BufferGeometry:
Каждая вершина содержит атрибут uv, который можно изменить
программно:const uvAttribute = geometry.attributes.uv;
for (let i = 0; i < uvAttribute.count; i++) {
const u = uvAttribute.getX(i);
const v = uvAttribute.getY(i);
uvAttribute.setXY(i, u * 0.5, v * 0.5); // масштабирование UV
}
uvAttribute.needsUpdate = true;
BoxProjection или сферическая проекция:geometry.computeBoundingBox();
const max = geometry.boundingBox.max;
const min = geometry.boundingBox.min;
const uvAttribute = new THREE.BufferAttribute(new Float32Array(geometry.attributes.position.count * 2), 2);
for (let i = 0; i < geometry.attributes.position.count; i++) {
const x = geometry.attributes.position.getX(i);
const y = geometry.attributes.position.getY(i);
const z = geometry.attributes.position.getZ(i);
const u = (x - min.x) / (max.x - min.x);
const v = (y - min.y) / (max.y - min.y);
uvAttribute.setXY(i, u, v);
}
geometry.setAttribute('uv', uvAttribute);
Этот способ полезен для плоских или кубических объектов.
Основные источники ошибок при маппинге:
Для исправления используют разделение UV-сегментов (islands) и корректировку масштаба каждой части вручную в редакторах типа Blender с последующим экспортом.
Three.js поддерживает несколько карт в одном материале:
map — основная текстура.aoMap — карта окружающего освещения.normalMap — карта нормалей для имитации
микродеталей.roughnessMap, metalnessMap,
displacementMap — специальные карты для
PBR-материалов.Для каждой карты важны корректные UV. aoMap и
displacementMap по умолчанию используют те же UV, что и
map, но можно использовать отдельный атрибут
uv2:
geometry.setAttribute('uv2', geometry.attributes.uv.clone());
material.aoMap = textureAO;
material.aoMapIntensity = 1.0;
Для отладки можно использовать LineSegments для визуального отображения сетки UV на модели. Это позволяет увидеть, какие участки текстуры применяются к полигонам и выявить растяжения.
const wireframe = new THREE.WireframeGeometry(geometry);
const line = new THREE.LineSegments(wireframe);
line.material.depthTest = false;
line.material.opacity = 0.5;
line.material.transparent = true;
scene.add(line);
aoMap
или displacementMap.Эффективная работа с UV и текстурами обеспечивает реалистичное отображение материала, позволяет корректно использовать PBR-материалы и минимизирует визуальные артефакты на моделях.