Глава 8 — Форматы экспорта


Что видно на изображении (2 991 Gaussians, SH-степень 3, синтетический букет из Blender как чистый по IP тестовый набор): Размеры под каждой карточкой формата рассчитываются в реальном времени из текущего количества Gaussians и накладных расходов формата — не зашиты жёстко. Из 2 991 Gaussians (SH-степень 3) получается 742 KB PLY, 74 KB SPZ (примерно в ~10× меньше за счёт квантования), 708 KB glTF (с расширением KHR_gaussian_splatting, поэтому практически эквивалентно PLY), 96 KB .splat (сжатый формат 24 байта на Gaussian). Orbit Video показывает «~Zero KB», потому что размер известен только после MP4-кодирования. Web Viewer (133 KB) упаковывает автономный HTML-файл со встроенным WebGL- просмотрщиком и сжатыми splat-данными — больше, чем чистый .splat, из-за накладных расходов на просмотрщик. История экспортов справа перечисляет уже выполненный PLY-экспорт («training_20260527T211321Z.ply, 743 KB, 23:13») со значком формата и действием Reveal-in-Finder.
Законченное обучение даёт облако Gaussians — набор из нескольких сотен тысяч или миллионов 3D-распределений Гаусса, которые вместе восстанавливают сцену. RadianceKit умеет десятью способами записать это облако на диск. Шесть из них — это чистые 3D-форматы данных (PLY, Compressed PLY, SPZ, SOG, glTF, .splat), один упаковывает облако вместе с готовым HTML-просмотрщиком (Web Viewer), один отрисовывает MP4-файл по орбитальной траектории камеры (Orbit Video), а два не экспортируют содержимое Gaussian, а только результат SfM (позы камер и грубое облако точек) для повторного использования в других конвейерах обучения (transforms.json + COLMAP Workspace).
Какой формат подходит в каком случае, зависит от цели. Для архивирования полных данных без потери качества берётся PLY. Для веб-просмотрщиков на собственной странице обычно достаточно .splat или встроенного Web Viewer. Если файл должен быть минимальным, стоит брать SPZ или SOG. Для повторного использования результата SfM в Nerfstudio, Postshot или Brush правильные пути — transforms.json и COLMAP Workspace.
Все функции экспорта находятся в меню «Export», а также в режиме новичка на последнем шаге мастера. Большинство форматов полностью совместимы с песочницей и работают в версии для App Store. Только SOG требует внешнего бинарного файла (cwebp), который не обязательно присутствует в сборке для App Store — подробности см. в E4.
E1 — PLY (.ply)
ГДЕ
Строка меню → Export → 3D Formats → Export PLY… (⌘E). Режим новичка: шаг мастера Export → карточка формата «PLY». Размер: обычно 100 % (опорное значение). Совместимо с: SuperSplat, PolyCam, все 3DGS-просмотрщики.
ТЕХНИЧЕСКИ
PLY — канонический формат хранения для 3D Gaussian Splatting. RadianceKit записывает двоичный little-endian файл со стандартизированной раскладкой свойств 3DGS: на один Gaussian — трёхкомпонентная позиция, три нормали всегда равны нулю, три DC-SH-коэффициента (f_dc_0..2) для базового RGB-цвета, далее до 45 дополнительных SH-коэффициентов (f_rest_0..44) в транспонированном channel-major-расположении, определённом статьёй Kerbl 2023 (сначала все коэффициенты канала R, затем все G, затем все B), за которыми следуют logit-непрозрачность (сырые значения до сигмоиды), три log-space-масштаба и кватернион поворота wxyz. Максимальная экспортируемая SH-степень ограничивается минимумом из пожелания пользователя и реально обученной степени; по умолчанию — 3 (45 rest-коэффициентов). Перед записью размер полезной нагрузки рассчитывается в 64-битном целочисленном виде, чтобы поймать переполнение на экстремально больших облаках. Файл пишется атомарно, что на больших облаках кратковременно занимает удвоенный объём диска.
E2 — Compressed PLY (.ply)
ГДЕ
Строка меню → Export → 3D Formats → Export Compressed PLY…. Режим новичка: карточка формата «Compressed PLY». Размер: прим. 10–20 % от PLY (5–10-кратное сжатие). Совместимо с: SuperSplat, движок PlayCanvas, веб- просмотрщики.
ТЕХНИЧЕСКИ
Вариант PlayCanvas формата PLY с chunked-квантованием. Gaussians группируются в чанки по 256. На чанк — min/max-границы для позиции, масштаба и цвета хранятся отдельно в заголовке; отдельные Gaussians ссылаются на свои значения относительно этих границ и сжимаются в 32 бита: позиция и масштаб с упаковкой 11-10-11 бит, поворот — как «Smallest-Three»-кватернион 2-10-10-10 бит, цвет — 8-8-8-8 RGBA. Высшие SH-коэффициенты квантуются с всего 8 битами на компоненту (shCoeffCount * 3 uchar на Gaussian). Сам формат всё ещё — ASCII-заголовок PLY и поэтому в принципе валидируется PLY- инструментами, но vertex-properties объявляются полями uint. SH-степень по умолчанию — 0 (нет rest-коэффициентов), чтобы максимизировать сжатие — более высокие SH-степени можно выбрать явно.
E3 — SPZ (.spz)
ГДЕ
Строка меню → Export → 3D Formats → Export SPZ…. Режим новичка: карточка формата «SPZ». Размер: прим. 10 % от PLY (на 90 % меньше). Совместимо с: Niantic Scaniverse, Niantic Spatial Fields, MetalSplatter.
ТЕХНИЧЕСКИ
Формат SPZ v2 от Niantic. Позиции упакованы как 24-битный fixed-point (что даёт разрешение около 0.25 мм), масштабы — как 8-битное квантование в логарифмическом пространстве, повороты — как 8-битный Smallest-Three (в v2 хранится только xyz, w выводится в декодере из нормы кватерниона), непрозрачности — как сигмоидированные 8-битные значения. DC SH хранится по специальной SPZ-формуле упаковки (dc_raw * 0.15 * 255 + 0.5 * 255), высшие SH-полосы — 5 битами (полоса 1) или 4 битами (полосы 2–3) на коэффициент. Весь упакованный двоичный блоб затем сжимается стандартным gzip (RFC 1952), что даёт gzip-контейнер с magic-байтами 1f 8b. RadianceKit вызывает для этого системный gzip, поскольку встроенный zlib-API Apple генерирует фирменное обрамление Apple, несовместимое с SPZ-читалками в Spatial Fields или MetalSplatter. Системный gzip к тому же остаётся запускаемым внутри песочницы macOS.
E4 — SOG (.sog)
ГДЕ
Строка меню → Export → 3D Formats → Export SOG…. Режим новичка: карточка формата «SOG». Размер: прим. 5–6 % от PLY (15–20-кратное сжатие — самый маленький вариант). Совместимо с: движок PlayCanvas, редактор SuperSplat.
ТЕХНИЧЕСКИ
«Spatially Ordered Gaussians» — формат PlayCanvas, который хранит облако в формате, готовом для GPU, в нескольких WebP-изображениях без потерь. Сначала все Gaussians сортируются пространственно через 3D-код Мортона (30-битный Z-порядок, по 10 бит на ось), что даёт изображениям кэш-локальность в рендерере. Затем позиции квантуются в 16-битные значения с симметричным логарифмическим преобразованием (для лучшего динамического диапазона) и разделяются на два RGBA-изображения (means_l.webp для младших 8 бит, means_u.webp для старших). Повороты кодируются как Smallest-Three с 3×8-битами плюс 2-битный режим в RGBA-изображении (режим попадает в альфа как 252 + largest). Масштабы и DC SH каждый квантуются с кодовой книгой на 256 записей (распределённой по перцентилям всех значений), индексы попадают в scales.webp и sh0.webp. Пять изображений плюс meta.json с кодовыми книгами и границами упаковываются в ZIP-файл (собственный энкодер, поскольку песочница блокирует системный zip) и сохраняются с расширением .sog.
Предупреждение о песочнице: SOG — единственный вариант формата, требующий внешний бинарный файл. Этап WebP-энкодера вызывает cwebp из /usr/local/bin/cwebp или /opt/homebrew/bin/cwebp. Если бинарный файл cwebp не найден, код откатывается к необработанному PNG-кодированию — но: PNG-fallback не работает в SuperSplat. В версии для App Store доступность оценивается по варианту сборки; в варианте для разработчиков cwebp должен быть установлен через Homebrew (brew install webp).
E5 — glTF (.glb)
ГДЕ
Строка меню → Export → 3D Formats → Export glTF…. Режим новичка: карточка формата «glTF». Размер: сопоставим с PLY. Совместимо с: glTF-просмотрщиками с расширением KHR_gaussian_splatting (черновой стандарт Khronos).
ТЕХНИЧЕСКИ
Записывает самодостаточный двоичный файл .glb (без отдельного приложения bin-файла) по спецификации расширения KHR_gaussian_splatting. Позиции хранятся как обычные glTF POSITION vertex-data (float3), все остальные атрибуты (поворот как float4, масштаб как float3, непрозрачность как float, SH-коэффициенты как float3 × shCoeffCount) находятся в дополнительных vertex-атрибутах и ссылаются через расширение. Важно: glTF использует правую систему координат с Y-up, тогда как COLMAP/3DGS работает в Y-down/Z-forward. Поэтому экспортёр применяет поворот на 180 градусов вокруг оси X — позиции переписываются как (x, -y, -z), кватернионы корректируются как (w, x, -y, -z). Это даёт геометрически корректное, правильно хиральное (не зеркальное) отображение в glTF- просмотрщиках. JSON- и двоичные чанки выровнены по 4-байтовой границе, как требует стандарт GLB.
E6 — Splat (.splat)
ГДЕ
Строка меню → Export → 3D Formats → Export .splat…. Режим новичка: карточка формата «.splat». Размер: ровно 32 байта на Gaussian. Совместимо с: gsplat.js, веб-просмотрщики (эталонная реализация antimatter15), большинство браузерных 3DGS-демо.
ТЕХНИЧЕСКИ
Формат .splat от antimatter15 — 32 байта на Gaussian, без заголовка, без косвенности. Раскладка на запись: 3 × float32 позиция (мировые координаты), 3 × float32 масштаб (exp-преобразование из логарифмического пространства внутреннего буфера), 4 × uint8 RGBA-цвет (DC-SH-коэффициент, масштабированный с SH_C0 = 0.282... и обрезанный в [0,255]), 4 × uint8 кватернион (w,x,y,z, нормализованный и закодированный в байтовом диапазоне как 128 + 128*q). Хранится только DC SH — высшие SH-полосы отбрасываются. Это делает формат чрезвычайно компактным, но стоит зависящих от направления взгляда изменений цвета, возникающих при отражениях или бликах. Порядок записи соответствует индексному порядку облака (без пространственной сортировки), веб-просмотрщики вроде gsplat.js рендерят, исходя из этого предположения.

flowers-01.html открыт напрямую из Finder двойным щелчком в браузере по умолчанию — встроенная программа WebGL2 немедленно рендерит облако Gaussian, без сети или сервера. Чёрные маркеры вокруг букета — тренировочные камеры, опционально переключаемые. Drag мышью вращает, scroll приближает.E7 — Web Viewer (.html)
ГДЕ
Строка меню → Export → Media → Export Web Viewer…. Режим новичка: карточка формата «Web Viewer». Размер: splat-данные в base64-кодировке (≈ 4/3 накладных) + прим. 5 KB HTML/JS-оболочка. Совместимо с: любым современным браузером с WebGL2 (все десктопы, iOS 15+, Android 5+).
ТЕХНИЧЕСКИ
Упаковывает облако Gaussian вместе с полностью встроенным WebGL2-рендерером в один файл .html. Нет зависимостей от CDN, нет WASM, нет второго файла. Облако внутри сначала кодируется как двоичный .splat (та же 32-байтовая логика, что у E6), потом встраивается в base64, потом декодируется atob в браузере. Встроенный рендерер делает собственную WebGL2-сортировку, mouse-orbit-controls и CPU-сортировку каждый кадр; весь JS-код (шейдер, математика, цикл) виден в выходном HTML. Соглашение об осях на границе хранения и рендерера — ровно такое же, как у E5: позиция (x, -y, -z), кватернион (w, x, -y, -z). Опционально может отображаться брендинг-оверлей (переключатель free-tier). Поскольку всё inline, файл работает и напрямую с протокола file:// — никакого локального веб-сервера для теста не нужно.

E8 — Orbit Video (.mp4/.mov)
ГДЕ
Строка меню → Viewport → Record Turntable Video ИЛИ строка меню → Export → Media → Export Orbit Video…. Режим новичка: карточка формата «Orbit Video» с ползунком длительности 3–30 с. Размер: зависит от длительности, разрешения, битрейта. Совместимо с: всеми платформами (H.264 и HEVC — стандарт Apple).
ТЕХНИЧЕСКИ
Рендерит облако Gaussian вдоль параметрической орбитальной траектории камеры и кодирует каждый кадр через AVAssetWriter в файл MP4 или MOV. Орбитальная конфигурация управляет скоростью вращения (revolutions), расстоянием, наклоном, FOV, длительностью и фактором ease-in/out. На кадр матрица настройки мира (рассчитанная рендерером для поворота внутренних координат в мир орбиты с Y-up) умножается на камеру, после чего применяется специфичное для MetalSplatter Y- зеркалирование. Цель оффскрин-рендеринга вытаскивается через IOSurface в CVPixelBuffer для энкодера. Энкодер поддерживает H.264 и HEVC, настраиваемый битрейт и разрешение от 480p до 8K. Перед первым кадром рендерер ждёт 200 мс, чтобы завершилась начальная сортировка splat. Этот экспорт ограничен GPU — при 8K и миллионах Gaussians время рендера на кадр составляет несколько секунд, так что суммарное время рендера 10–30 минут для 6 с видео вполне возможно.
E9 — SfM Transforms (transforms.json)
ГДЕ
Строка меню → Export → Photogrammetry → Export SfM (transforms.json)…. Размер: обычно 1–10 KB (только позы + intrinsics, без изображений, без Gaussians). Совместимо с: nerfstudio, Brush, gsplat, OpenSplat, Meshroom, со всеми современными feed-forward 3DGS-тренировщиками.
ТЕХНИЧЕСКИ
Записывает формат transforms.json от nerfstudio со списком поз камер плюс общие intrinsics. На камеру view-матрица (внутреннее представление RadianceKit: World-to-Camera в соглашении COLMAP) инвертируется, после чего камеро-локальные векторы базиса Y и Z зеркалируются для конвертации в соглашение nerfstudio (стиль OpenGL, камера смотрит вдоль -Z, +Y направлено вверх). Финальная матрица 4×4 попадает как row-major вложенный массив double в поле transform_matrix каждого кадра. Intrinsics хранятся на верхнем уровне (focal length x/y, principal point x/y, ширина/высота изображения, camera_model = "OPENCV", плюс коэффициенты искажения k1, k2, p1, p2) — кроме случая, когда экспортёр обнаруживает несколько разных наборов intrinsics, тогда они пишутся на кадр. Пути изображений пишутся как images/<filename> относительно JSON-файла; пользователь должен создать соседнюю папку images/ с тренировочными фотографиями.
E10 — COLMAP Workspace (sparse/0/)
ГДЕ
Строка меню → Export → Photogrammetry → Export SfM (COLMAP Workspace)…. Размер: три двоичных файла вместе обычно 4–8 MB — points3D.bin доминирует (одна строка на каждую 3D-точку sparse-облака), images.bin и cameras.bin — каждый заметно меньше 100 KB. Совместимо с: самим COLMAP, Nerfstudio, Postshot, Meshroom, всеми инструментами, ожидающими директорию COLMAP sparse/.
ТЕХНИЧЕСКИ
Записывает стандартную раскладку COLMAP sparse/0/ с тремя двоичными файлами: cameras.bin, images.bin, points3D.bin. Эталон формата — официальная документация COLMAP. cameras.bin содержит дедуплицированный список intrinsics (камеры с идентичными intrinsics + размером изображения объединяются в одну запись); используемая модель камеры — OPENCV (model 4), с fx/fy/cx/cy плюс четыре коэффициента искажения k1/k2/p1/p2. images.bin перечисляет на каждое изображение позу как wxyz-кватернион плюс перемещение, за которым следует ID камеры и имя файла; 2D-3D-соответствия не сохраняются. points3D.bin содержит SfM-облако точек с позицией, цветом (0–255 RGB) и значениями по умолчанию для репроекции и длины треков. Всё пишется в little-endian. Повторный импорт в RadianceKit работает через меню File → «Import COLMAP/Metashape Workspace…» (см. Q3 в главе про SfM-бэкенды).
Какой формат когда?
| Цель | Формат |
|---|---|
| Веб-просмотрщик на своей странице | E7 Web Viewer (.html) |
Веб-просмотрщик с gsplat.js | E6 Splat (.splat) |
| Повторное использование в конвейере Postshot / Nerfstudio | E9 transforms.json + E10 COLMAP Workspace |
| Редактирование в SuperSplat | E1 PLY или E2 Compressed PLY |
| Niantic Scaniverse / Spatial Fields | E3 SPZ |
| Максимальное сжатие | E4 SOG (требуется cwebp) |
| Маркетинговое/соцсетевое видео | E8 Orbit Video |
Быстрое сравнение
| Формат | Расширение | Песочница | Размер (1M Gauss) | Лучшее применение |
|---|---|---|---|---|
| E1 PLY | .ply | да | ~250 MB | Архив, наивысшая совместимость |
| E2 Compressed PLY | .ply | да | ~40 MB | Веб + SuperSplat |
| E3 SPZ | .spz | да (gzip spawn) | ~40 MB | Niantic + мобильные |
| E4 SOG | .sog | условно (cwebp) | ~20 MB | Максимальное сжатие |
| E5 glTF | .glb | да | ~250 MB | Конвейер Khronos |
| E6 Splat | .splat | да | ~32 MB | gsplat.js веб- просмотрщик |
| E7 Web Viewer | .html | да | ~45 MB | Автономный браузерный файл |
| E8 Orbit Video | .mp4/.mov | да | переменно | Соцсети/маркетинг |
| E9 SfM Transforms | .json | да | ~5 KB | Передача поз |
| E10 COLMAP Workspace | Директория | да | ~4–8 MB | Передача поз двоично |
Колонка размера — грубые опорные значения для 1 миллиона Gaussians с SH-степенью 3. Реальные значения варьируются в зависимости от сжимаемости сцены; SH-степень 0 уменьшает PLY/glTF в 4 раза.