Сериализация и десериализация сцены: ObjectLoader

В библиотеке Three.js работа с трехмерными сценами включает возможность сохранения и восстановления их состояния. Для этих целей используется класс THREE.ObjectLoader, предназначенный для сериализации (преобразования объектов сцены в JSON) и десериализации (восстановления объектов из JSON). Этот процесс необходим для передачи сцен по сети, сохранения конфигураций, а также для динамического построения сцены из внешних источников.


Основные принципы работы ObjectLoader

ObjectLoader позволяет:

  • Загружать и восстанавливать полные сцены с камерами, объектами, материалами и текстурами.
  • Воссоздавать иерархию объектов, включая родительско-дочерние связи.
  • Обрабатывать все типы объектов Three.js: Mesh, Group, Camera, Light и пользовательские объекты.

Схема работы:

  1. Сериализация: объект сцены превращается в JSON через метод scene.toJSON().
  2. Десериализация: JSON передается в ObjectLoader.parse(json) или загружается через ObjectLoader.load(url, onLoad).

Сериализация сцены

Сериализация сцены выполняется методом toJSON(), который доступен у всех объектов, наследующихся от THREE.Object3D.

Пример:

import * as THREE from 'three';

const scene = new THREE.Scene();

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

scene.add(cube);

const json = scene.toJSON();
console.log(JSON.stringify(json, null, 2));

Особенности:

  • JSON включает описание всех объектов, их геометрии, материалов и текстур.
  • Иерархия сцены сохраняется: дочерние объекты будут привязаны к своим родителям.
  • При сохранении текстур и материалов можно использовать отдельное хранение через THREE.MaterialLoader и THREE.TextureLoader, но ObjectLoader автоматически сериализует большинство стандартных материалов.

Десериализация сцены

Для восстановления сцены используется THREE.ObjectLoader. Он может работать с локальными объектами JSON или загружать их по URL.

Пример десериализации из JSON:

import * as THREE from 'three';

const loader = new THREE.ObjectLoader();

const sceneJson = /* JSON из предыдущего примера */;
const loadedScene = loader.parse(sceneJson);

console.log(loadedScene); // Восстановленная сцена с кубом

Пример загрузки JSON по URL:

loader.load('scene.json', function(loadedScene) {
    console.log('Сцена загружена', loadedScene);
});

Особенности:

  • Все объекты сцены восстанавливаются с их типами и иерархией.
  • Материалы и геометрия создаются заново, ссылки на текстуры корректно привязываются.
  • Если сцена содержит пользовательские объекты или нестандартные классы, необходимо расширять ObjectLoader через loader.setCustomObjectLoader(name, callback).

Работа с пользовательскими объектами

Three.js позволяет создавать классы, наследующиеся от THREE.Object3D. Для корректной сериализации и десериализации таких объектов используется регистрация кастомного обработчика.

class CustomCube extends THREE.Mesh {
    constructor() {
        super(new THREE.BoxGeometry(1, 1, 1), new THREE.MeshStandardMaterial({ color: 0xff0000 }));
    }
    toJSON(meta) {
        const data = super.toJSON(meta);
        data.userData.customFlag = true;
        return data;
    }
}

const loader = new THREE.ObjectLoader();
loader.setCustomObjectLoader('CustomCube', function(data) {
    const obj = new CustomCube();
    obj.userData = data.userData;
    return obj;
});

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

При сериализации ObjectLoader автоматически сохраняет свойства материалов и текстур. Однако есть нюансы:

  • Некоторые текстуры могут быть сериализованы как ссылки на изображения (image.src).
  • Для больших текстур рекомендуется хранить их отдельно и указывать путь в JSON.
  • Материалы с шейдерами (ShaderMaterial) требуют ручной сериализации пользовательских uniform-параметров.

Практические советы

  • Хранение сцены на сервере: сериализованную сцену удобно хранить в формате JSON, который затем можно загружать через ObjectLoader.load().
  • Оптимизация: для больших сцен отключать сериализацию ненужных свойств через object.toJSON(meta) с пользовательским meta.
  • Версионирование: сохранять версию сцены (userData.version) для совместимости при изменении структуры объектов.

Методы ObjectLoader

  • parse(json) — десериализация объекта/сцены из JSON.
  • load(url, onLoad, onProgress, onError) — загрузка JSON-файла по URL.
  • setCustomObjectLoader(type, callback) — регистрация кастомного обработчика для нестандартных объектов.
  • setTexturePath(path) — базовый путь для текстур, если они сериализованы как пути к файлам.

Эти методы позволяют гибко управлять сценой, восстанавливать сложные иерархии объектов и интегрировать кастомные элементы без потери информации.


Примеры использования в реальных проектах

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

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