GLTFLoader: основной формат 3D-моделей

Three.js предоставляет встроенные средства для работы с форматом GLTF (GL Transmission Format), который является современным стандартом для обмена 3D-контентом. Этот формат поддерживает геометрию, материалы, анимации, камеры и текстуры, упрощая перенос моделей между различными платформами и движками.

Подключение GLTFLoader

Для загрузки моделей в формате .gltf или .glb используется класс GLTFLoader. Он является частью официального репозитория Three.js и подключается через модуль:

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

Создание загрузчика и его базовое использование:

const loader = new GLTFLoader();
loader.load('models/model.glb', function (gltf) {
    scene.add(gltf.scene);
}, undefined, function (error) {
    console.error(error);
});

Ключевые моменты:

  • gltf.scene — основной объект сцены из файла, который можно добавлять в Three.js сцену.
  • onLoad — коллбек успешной загрузки.
  • onProgress — опциональный коллбек для отслеживания прогресса.
  • onError — обработка ошибок при загрузке.

Структура объекта GLTF

После загрузки объект gltf содержит несколько важных свойств:

  • gltf.scene — корневой объект THREE.Group, содержащий все меши и светильники модели.
  • gltf.animations — массив анимаций (THREE.AnimationClip).
  • gltf.cameras — список камер, определенных в модели.
  • gltf.asset — информация о версии формата и метаданных.

Для анимаций используется THREE.AnimationMixer:

const mixer = new THREE.AnimationMixer(gltf.scene);
const action = mixer.clipAction(gltf.animations[0]);
action.play();

Необходимо обновлять миксер на каждом кадре в animate:

const clock = new THREE.Clock();

function animate() {
    requestAnimationFrame(animate);
    const delta = clock.getDelta();
    mixer.update(delta);
    renderer.render(scene, camera);
}
animate();

Поддержка бинарного формата .glb

Формат .glb представляет собой бинарную версию GLTF и позволяет упаковать геометрию, материалы и текстуры в один файл. Для Three.js загрузка .glb идентична .gltf:

loader.load('models/model.glb', function (gltf) {
    scene.add(gltf.scene);
});

Работа с материалами и текстурами

GLTFLoader автоматически импортирует PBR-материалы (THREE.MeshStandardMaterial или THREE.MeshPhysicalMaterial). Материалы могут содержать:

  • Base Color Map — основной цвет.
  • Metalness Map — коэффициент металличности.
  • Roughness Map — шероховатость поверхности.
  • Normal Map — нормали для детализации рельефа.

Для замены материалов после загрузки:

gltf.scene.traverse((child) => {
    if (child.isMesh) {
        child.material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
    }
});

Оптимизация и сжатие моделей

GLTF поддерживает сжатие геометрии через draco-compression, что уменьшает размер файлов и ускоряет загрузку. Для использования сжатых моделей необходим DRACOLoader:

import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';

const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('js/libs/draco/');

const loader = new GLTFLoader();
loader.setDRACOLoader(dracoLoader);
loader.load('models/model_draco.glb', function (gltf) {
    scene.add(gltf.scene);
});

Важные детали:

  • Draco-декодер загружается отдельно и должен быть указан с помощью setDecoderPath.
  • Загрузка сжатых моделей требует меньше памяти и сети, но декодирование выполняется на клиенте.

Анимации и взаимодействие

GLTF поддерживает скелетные анимации, морф-таргеты и камеры. Для сложных взаимодействий используется комбинация AnimationMixer и событий пользовательского интерфейса. Пример плавного перехода между анимациями:

const action1 = mixer.clipAction(gltf.animations[0]);
const action2 = mixer.clipAction(gltf.animations[1]);

action1.play();
action1.crossFadeTo(action2, 0.5, false);

Интеграция с другими объектами Three.js

GLTF-модели можно комбинировать с любыми объектами Three.js: светильниками, частицами, физикой. Для взаимодействия с внешними библиотеками, такими как cannon-es или ammo.js, достаточно использовать позицию и вращение gltf.scene:

physicsBody.position.copy(gltf.scene.position);
physicsBody.quaternion.copy(gltf.scene.quaternion);

Поддержка нескольких сцен

Файл GLTF может содержать несколько сцен. По умолчанию gltf.scene — это первая сцена, но доступны все через gltf.scenes:

scene.add(gltf.scenes[1]);

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

Преобразование моделей

Для оптимизации отображения или изменения масштаба:

gltf.scene.scale.set(2, 2, 2);
gltf.scene.position.set(0, 0, 0);
gltf.scene.rotation.y = Math.PI / 4;

Использование traverse позволяет модифицировать отдельные меши, материалы или текстуры в сцене без изменения всей модели.


Three.js с GLTFLoader обеспечивает полный цикл работы с современными 3D-моделями, включая загрузку, анимацию, материалы, оптимизацию и интеграцию в интерактивные сцены. Этот подход является стандартом для веб-приложений с высококачественной графикой и поддержкой сложной анимации.