FBXLoader

Формат FBX (Filmbox) широко используется в индустрии 3D-графики для обмена моделями, анимациями, ригами и материалами между различными программами: Blender, Autodesk Maya, 3ds Max, Cinema 4D и другими. В среде веб-разработки данный формат применяется для переноса готовых 3D-ассетов в браузерные приложения.

В библиотеке Three.js загрузка таких файлов осуществляется с помощью класса FBXLoader, входящего в модуль расширений examples/jsm/loaders. Загрузчик анализирует структуру файла FBX, извлекает геометрию, материалы, текстуры и анимационные данные, после чего преобразует их в объекты Three.js.

FBXLoader поддерживает:

  • статические 3D-модели
  • скелетную анимацию
  • анимационные клипы
  • иерархию объектов
  • встроенные текстуры и материалы
  • трансформации и систему костей

После загрузки объект возвращается в виде структуры THREE.Group, содержащей набор Mesh, SkinnedMesh, Bone и других компонентов сцены.


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

FBXLoader не входит в основной пакет Three.js и подключается отдельно из каталога examples.

Пример подключения через ES-модули:

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

После импорта можно создать экземпляр загрузчика:

const loader = new FBXLoader();

Загрузчик не требует обязательной предварительной конфигурации, однако может быть связан с менеджером загрузок (LoadingManager) для отслеживания прогресса или управления путями к ресурсам.


Базовая загрузка FBX-модели

Метод load() выполняет асинхронную загрузку и парсинг файла.

Сигнатура метода:

loader.load(url, onLoad, onProgress, onError);

Параметры:

Параметр Назначение
url путь к FBX-файлу
onLoad функция, вызываемая после успешной загрузки
onProgress обработчик прогресса загрузки
onError обработчик ошибок

Пример:

const loader = new FBXLoader();

loader.load('models/character.fbx', function (object) {

    scene.add(object);

});

В обработчик onLoad передаётся объект сцены, содержащий структуру модели.


Добавление модели в сцену

После загрузки FBX-файл представляет собой иерархию объектов, аналогичную сцене в редакторах 3D-графики.

Пример базовой интеграции:

loader.load('models/robot.fbx', (object) => {

    object.scale.set(0.01, 0.01, 0.01);
    object.position.set(0, 0, 0);

    scene.add(object);

});

Часто требуется масштабирование модели, поскольку единицы измерения FBX-файла могут отличаться от используемых в Three.js.


Структура загруженного объекта

FBXLoader преобразует данные FBX в структуру, состоящую из стандартных классов Three.js:

  • THREE.Group
  • THREE.Mesh
  • THREE.SkinnedMesh
  • THREE.Bone
  • THREE.AnimationClip

Типичный объект может выглядеть следующим образом:

Group
 ├── Mesh
 ├── Mesh
 └── SkinnedMesh
       └── Skeleton

Иерархия сохраняет оригинальные трансформации, применённые в 3D-редакторе.

Для обхода структуры применяется метод traverse().

Пример:

loader.load('model.fbx', (object) => {

    object.traverse((child) => {

        if (child.isMesh) {
            child.castShadow = true;
            child.receiveShadow = true;
        }

    });

    scene.add(object);

});

Метод traverse() позволяет выполнять настройку каждого дочернего объекта.


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

FBXLoader автоматически преобразует материалы из FBX-формата в материалы Three.js, чаще всего:

  • MeshPhongMaterial
  • MeshStandardMaterial

Иногда требуется дополнительная настройка.

Пример замены материалов:

object.traverse((child) => {

    if (child.isMesh) {

        child.material = new THREE.MeshStandardMaterial({
            color: 0xffffff,
            metalness: 0.5,
            roughness: 0.5
        });

    }

});

Такой подход используется, если исходные материалы несовместимы с системой освещения сцены.


Поддержка текстур

FBX-файлы могут содержать:

  • встроенные текстуры
  • ссылки на внешние изображения

FBXLoader автоматически загружает связанные текстуры, если пути к ним корректны.

При необходимости указывается базовый путь:

loader.setPath('models/');
loader.setResourcePath('textures/');

setPath() определяет директорию модели, а setResourcePath() — каталог для текстур.


Скелетная анимация

Одной из ключевых возможностей FBXLoader является поддержка skeletal animation — анимации, основанной на системе костей.

Такая модель представляется объектом SkinnedMesh, содержащим:

  • скелет (Skeleton)
  • кости (Bone)
  • анимационные клипы (AnimationClip)

Для воспроизведения анимации используется AnimationMixer.

Пример:

const mixer = new THREE.AnimationMixer(object);

const action = mixer.clipAction(object.animations[0]);
action.play();

Обновление микшера происходит в основном цикле рендеринга:

const clock = new THREE.Clock();

function animate() {

    requestAnimationFrame(animate);

    const delta = clock.getDelta();

    mixer.update(delta);

    renderer.render(scene, camera);

}

AnimationMixer интерполирует ключевые кадры и применяет их к костям модели.


Работа с несколькими анимациями

FBX-файл может содержать несколько анимационных клипов. Они хранятся в массиве object.animations.

Пример перебора:

object.animations.forEach((clip) => {

    const action = mixer.clipAction(clip);
    action.play();

});

Каждый клип можно запускать отдельно.

Пример выбора конкретной анимации:

const walk = THREE.AnimationClip.findByName(object.animations, 'Walk');

const action = mixer.clipAction(walk);
action.play();

Оптимизация FBX-моделей

FBX-файлы часто имеют значительный размер и сложную структуру. Для веб-приложений важна оптимизация.

Основные рекомендации:

1. Уменьшение количества полигонов

Высокополигональные модели негативно влияют на производительность браузера.

2. Удаление ненужных анимаций

Лишние анимационные клипы увеличивают объём файла.

3. Сжатие текстур

Использование форматов:

  • JPEG
  • WebP
  • KTX2

4. Конвертация в glTF

Хотя FBXLoader поддерживает формат FBX, формат glTF считается более оптимальным для веб-графики. FBX часто используется как промежуточный формат, который затем конвертируется.


Асинхронная загрузка через Promise

Метод loadAsync() предоставляет удобный интерфейс для работы с async/await.

Пример:

const loader = new FBXLoader();

async function loadModel() {

    const object = await loader.loadAsync('model.fbx');

    scene.add(object);

}

loadModel();

Такой подход упрощает управление асинхронными операциями и уменьшает вложенность колбэков.


Использование LoadingManager

LoadingManager позволяет отслеживать процесс загрузки ресурсов.

Пример:

const manager = new THREE.LoadingManager();

manager.onSt art = () => console.log('Загрузка началась');
manager.onProgr ess = (url, loaded, total) => console.log(loaded, total);
manager.onL oad = () => console.log('Все ресурсы загружены');

const loader = new FBXLoader(manager);

Менеджер полезен при загрузке большого количества моделей и текстур.


Обработка ошибок загрузки

Ошибки могут возникать по различным причинам:

  • неверный путь к файлу
  • отсутствие текстур
  • повреждённый FBX
  • несовместимая версия формата

Пример обработки:

loader.load(
    'model.fbx',
    (object) => {
        scene.add(object);
    },
    undefined,
    (error) => {
        console.error('Ошибка загрузки FBX:', error);
    }
);

Особенности формата FBX

Формат FBX имеет ряд особенностей, влияющих на работу в Three.js.

1. Большой размер файлов

FBX содержит подробную информацию о сцене, что увеличивает объём данных.

2. Различные версии формата

FBXLoader корректно работает не со всеми версиями FBX. Иногда требуется экспорт в более раннюю версию (например, FBX 2013).

3. Координатные системы

3D-редакторы используют разные оси:

Программа Ось вверх
Blender Z
Maya Y
Three.js Y

В результате может потребоваться корректировка вращения модели.


Изменение трансформаций модели

После загрузки объект можно свободно трансформировать.

Пример:

object.rotation.y = Math.PI / 2;
object.position.set(0, 0, 5);
object.scale.set(0.5, 0.5, 0.5);

Все дочерние элементы модели наследуют эти преобразования.


Предварительная обработка модели

Часто выполняется дополнительная настройка:

  • включение теней
  • пересчёт нормалей
  • замена материалов
  • оптимизация геометрии

Пример:

object.traverse((child) => {

    if (child.isMesh) {

        child.castShadow = true;
        child.receiveShadow = true;

        child.geometry.computeVertexNormals();

    }

});

Такая обработка улучшает визуальное качество рендеринга.


Ограничения FBXLoader

Несмотря на широкую поддержку FBX, существуют ограничения:

  • не все типы материалов корректно конвертируются
  • некоторые контроллеры анимации могут быть потеряны
  • сложные нодовые материалы не поддерживаются
  • возможны различия в освещении между редактором и браузером

По этой причине для production-проектов часто используется предварительная конвертация моделей в glTF.