Экспорт сцены в glTF через GLTFExporter

Three.js предоставляет мощные инструменты для создания и управления 3D-сценами в браузере. Одной из ключевых возможностей является экспорт сцены или отдельных объектов в формат glTF — современный стандарт для обмена 3D-данными, оптимизированный для веба и движков реального времени.


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

Для работы с экспортом используется класс GLTFExporter, который входит в модуль examples/jsm/exporters/GLTFExporter.js. В современных проектах с использованием ES6-модулей подключение выглядит так:

import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';

Если используется стандартный скриптовый тег, необходимо подключить файл из папки examples библиотеки Three.js.


Создание экземпляра экспортера

Экземпляр экспортера создается простым вызовом конструктора:

const exporter = new GLTFExporter();

Экспортер поддерживает два типа экспорта: JSON (glTF) и бинарный (glb).

  • JSON (текстовый) – удобен для отладки и ручного редактирования.
  • Binary (glb) – компактный, содержит все ресурсы в одном файле, включая текстуры.

Экспорт сцены или объекта

Метод parse является основным для экспорта. Он принимает три аргумента:

  1. объект Three.js — сцена, группа или меш.
  2. callback — функция, которая получает результат экспорта.
  3. options — объект с настройками экспорта.

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

exporter.parse(
    scene, 
    function(result) {
        if (result instanceof ArrayBuffer) {
            saveArrayBuffer(result, 'scene.glb');
        } else {
            const output = JSON.stringify(result, null, 2);
            saveString(output, 'scene.gltf');
        }
    },
    {
        binary: true,
        embedImages: true,
        trs: false,
        onlyVisible: true,
        includeCustomExtensions: true
    }
);

Ключевые опции:

  • binary — устанавливает формат glb, по умолчанию false.
  • embedImages — встраивает текстуры в файл, иначе создаются отдельные файлы.
  • trs — сохраняет трансформации в виде translation, rotation, scale вместо матриц.
  • onlyVisible — экспортирует только видимые объекты сцены.
  • includeCustomExtensions — сохраняет кастомные расширения.

Сохранение файлов

Для сохранения результата используется стандартный способ создания ссылок на Blob:

function saveArrayBuffer(buffer, filename) {
    const blob = new Blob([buffer], { type: 'application/octet-stream' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = filename;
    link.click();
}

function saveString(text, filename) {
    const blob = new Blob([text], { type: 'text/plain' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = filename;
    link.click();
}

Этот метод позволяет скачать файл напрямую из браузера без сервера.


Экспорт анимаций

GLTFExporter поддерживает экспорт анимаций, включая Skeleton и MorphTarget. Для этого объект должен содержать AnimationClip:

import { AnimationMixer, AnimationClip } from 'three';

const mixer = new AnimationMixer(mesh);
const clip = AnimationClip.findByName(mesh.animations, 'Walk');
mixer.clipAction(clip).play();

exporter.parse(scene, function(result) {
    saveArrayBuffer(result, 'scene_with_animation.glb');
}, { binary: true });

Анимации корректно сохраняются в формате glTF и могут быть воспроизведены в других движках.


Ограничения и особенности

  • Экспорт текстур в формате DataTexture или с нестандартными параметрами может требовать ручной обработки.
  • Некоторые нестандартные материалы или шейдеры, созданные через ShaderMaterial, не сохраняются корректно без кастомных расширений.
  • Метки userData и кастомные свойства объектов можно сохранить, используя includeCustomExtensions.

Оптимизация сцены перед экспортом

Для уменьшения размера файла рекомендуется:

  1. Удалять невидимые объекты (onlyVisible: true).
  2. Объединять геометрию (BufferGeometryUtils.mergeBufferGeometries).
  3. Использовать текстуры с низким разрешением для предварительного просмотра.
  4. Удалять вспомогательные объекты, например AxesHelper или GridHelper.

Пример комплексного экспорта

import { Scene, PerspectiveCamera, WebGLRenderer, Mesh, BoxGeometry, MeshStandardMaterial } from 'three';
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';

const scene = new Scene();
const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const geometry = new BoxGeometry();
const material = new MeshStandardMaterial({ color: 0x00ff00 });
const cube = new Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;

const exporter = new GLTFExporter();

exporter.parse(scene, function(result) {
    const output = JSON.stringify(result, null, 2);
    saveString(output, 'full_scene.gltf');
}, { binary: false, onlyVisible: true });

Этот пример демонстрирует базовый процесс создания сцены и её экспорта в текстовый формат glTF с сохранением видимых объектов.


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