Формат FBX (Filmbox) широко используется в индустрии 3D-графики для обмена моделями, анимациями, ригами и материалами между различными программами: Blender, Autodesk Maya, 3ds Max, Cinema 4D и другими. В среде веб-разработки данный формат применяется для переноса готовых 3D-ассетов в браузерные приложения.
В библиотеке Three.js загрузка таких файлов
осуществляется с помощью класса FBXLoader, входящего в
модуль расширений examples/jsm/loaders. Загрузчик
анализирует структуру файла FBX, извлекает геометрию, материалы,
текстуры и анимационные данные, после чего преобразует их в объекты
Three.js.
FBXLoader поддерживает:
После загрузки объект возвращается в виде структуры
THREE.Group, содержащей набор Mesh,
SkinnedMesh, Bone и других компонентов
сцены.
FBXLoader не входит в основной пакет Three.js и подключается отдельно из каталога examples.
Пример подключения через ES-модули:
import * as THREE from 'three';
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
После импорта можно создать экземпляр загрузчика:
const loader = new FBXLoader();
Загрузчик не требует обязательной предварительной конфигурации,
однако может быть связан с менеджером загрузок
(LoadingManager) для отслеживания прогресса или управления
путями к ресурсам.
Метод 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.GroupTHREE.MeshTHREE.SkinnedMeshTHREE.BoneTHREE.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, чаще всего:
MeshPhongMaterialMeshStandardMaterialИногда требуется дополнительная настройка.
Пример замены материалов:
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-файлы часто имеют значительный размер и сложную структуру. Для веб-приложений важна оптимизация.
Основные рекомендации:
1. Уменьшение количества полигонов
Высокополигональные модели негативно влияют на производительность браузера.
2. Удаление ненужных анимаций
Лишние анимационные клипы увеличивают объём файла.
3. Сжатие текстур
Использование форматов:
4. Конвертация в glTF
Хотя FBXLoader поддерживает формат FBX, формат glTF считается более оптимальным для веб-графики. FBX часто используется как промежуточный формат, который затем конвертируется.
Метод loadAsync() предоставляет удобный интерфейс для
работы с async/await.
Пример:
const loader = new FBXLoader();
async function loadModel() {
const object = await loader.loadAsync('model.fbx');
scene.add(object);
}
loadModel();
Такой подход упрощает управление асинхронными операциями и уменьшает вложенность колбэков.
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);
Менеджер полезен при загрузке большого количества моделей и текстур.
Ошибки могут возникать по различным причинам:
Пример обработки:
loader.load(
'model.fbx',
(object) => {
scene.add(object);
},
undefined,
(error) => {
console.error('Ошибка загрузки FBX:', error);
}
);
Формат 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();
}
});
Такая обработка улучшает визуальное качество рендеринга.
Несмотря на широкую поддержку FBX, существуют ограничения:
По этой причине для production-проектов часто используется предварительная конвертация моделей в glTF.