Quantized-mesh формат

Quantized-mesh представляет собой специализированный формат хранения данных рельефа, ориентированный на эффективную передачу и визуализацию глобальных и локальных поверхностей в WebGL-рендерерах. Основная идея заключается в том, чтобы заменить классические heightmap-растры треугольной сеткой, где координаты вершин квантованы до целочисленного диапазона, что позволяет значительно сократить объём данных при сохранении геометрической точности после декодирования на клиенте.

Каждый тайл представляет собой независимый фрагмент поверхности, описанный набором вершин, индексов треугольников, метаданных об ограничивающих объёмах и вспомогательных структур для сшивки соседних тайлов.


Квантование координат вершин

В основе формата лежит квантование координат в диапазон фиксированной битности, чаще всего 16 бит на каждую компоненту внутри тайла.

Для каждой вершины хранятся нормализованные координаты:

  • u ∈ [0, 1]
  • v ∈ [0, 1]
  • h ∈ [0, 1]

где:

  • u, v — координаты в пространстве тайла (долгота/широта или проекция)
  • h — нормализованная высота относительно минимальной и максимальной высоты тайла

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

x = x_min + u * (x_max - x_min) y = y_min + v * (y_max - y_min) z = h_min + h * (h_max - h_min)

Такое представление позволяет:

  • уменьшить размер буфера вершин
  • ускорить загрузку
  • эффективно использовать GPU-интерполяцию после декодирования

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

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

Особенности индексации:

  • используется triangle list
  • отсутствуют дублирующиеся вершины на внутренних гранях
  • поддерживается оптимизация для GPU cache coherence

Дополнительно вводятся специальные индексы для “skirt”-геометрии — вертикальных полос по краям тайла, предотвращающих появление щелей между уровнями детализации.


Skirts и устранение швов

Skirt-геометрия представляет собой расширение края тайла вниз по оси высоты. Она добавляется как дополнительный набор вершин и треугольников вдоль границ сетки.

Назначение:

  • скрытие щелей между LOD-уровнями
  • компенсация различий высот соседних тайлов
  • устранение артефактов при неполном совпадении границ

Skirt вершины создаются путём дублирования граничных вершин с искусственным снижением высоты:

z_skirt = z_original - δ

где δ — фиксированное смещение вниз, зависящее от масштаба тайла.


Метаданные тайла

Каждый quantized-mesh тайл содержит набор служебной информации:

Bounding volume

Используется для отсечения невидимых тайлов на этапе culling.

Формы представления:

  • bounding sphere
  • oriented bounding box (в некоторых реализациях)

Bounding sphere задаётся как:

  • центр (cx, cy, cz)
  • радиус r

Horizon occlusion

Для ускорения глобального рендеринга используется horizon-based culling. Каждый тайл хранит данные, позволяющие оценить его потенциальную видимость относительно горизонта камеры.

Это позволяет:

  • отбрасывать тайлы за горизонтом
  • уменьшать количество draw calls
  • ускорять traversal quadtree

Edge indices

Для корректного соединения тайлов различного уровня детализации используются маски границ:

  • left edge
  • right edge
  • top edge
  • bottom edge

Каждая грань может содержать набор индексов, которые используются для stitching алгоритмов между родительскими и дочерними тайлами.


Oct-encoded normals

Нормали поверхности часто хранятся в сжатом виде с использованием octahedral encoding.

Идея заключается в проекции единичного вектора нормали на октаэдр с последующей нормализацией в 2D пространство:

  • хранится (nx, ny) в диапазоне [0, 1]
  • nz восстанавливается на клиенте

Восстановление:

nz = sqrt(1 - nx² - ny²)

После декодирования получается полноценная нормаль для освещения.

Такой метод обеспечивает:

  • уменьшение объёма данных в 2 раза по сравнению с float32 нормалями
  • высокую точность при малых углах поверхности

Структура файла тайла

Типичный quantized-mesh файл содержит бинарную структуру:

  1. Header
  2. Vertex quantization parameters
  3. Vertex buffer
  4. Index buffer
  5. Edge indices
  6. Bounding volumes
  7. Horizon occlusion data
  8. Water mask (опционально)
  9. Per-vertex attributes (нормали, цвета)

Header фиксирует смещения секций и версию формата.


Водяная маска (water mask)

Water mask используется для различения суши и водных поверхностей в рендеринге.

Представляет собой растровый слой низкого разрешения, где:

  • 0 — суша
  • 1 — вода

Маска применяется в шейдерах для:

  • изменения отражений
  • корректировки альбедо
  • отключения теней под водой

Иерархия тайлов и LOD

Quantized-mesh тесно связан с quadtree-структурой.

Каждый тайл имеет:

  • родительский узел
  • до четырёх дочерних узлов

LOD выбирается на основе:

  • расстояния до камеры
  • угла обзора
  • экранного error metric

Error metric обычно вычисляется как максимальное отклонение между упрощённой и детальной поверхностью.


Взаимодействие с CesiumJS

В CesiumJS quantized-mesh используется в terrain provider слоях.

Процесс загрузки:

  1. Камера запрашивает тайлы по quadtree
  2. Сервер возвращает бинарный quantized-mesh файл
  3. Клиент декодирует вершины
  4. Генерируется WebGL буфер
  5. Применяются skirts и stitching
  6. Тайлы попадают в render queue

CesiumJS автоматически управляет:

  • кэшированием тайлов
  • приоритетами загрузки
  • динамическим LOD

Особенности декодирования на клиенте

Декодирование выполняется полностью в JavaScript и WebGL пайплайне.

Ключевые этапы:

  • распаковка бинарного массива
  • преобразование quantized координат в мировые
  • восстановление нормалей
  • построение индексов
  • генерация GPU буферов

Оптимизация достигается за счёт:

  • использования TypedArray
  • минимизации GC-аллоцирования
  • повторного использования буферов

Геометрическая точность и ошибки аппроксимации

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

Источники ошибки:

  • квантование координат
  • упрощение mesh при генерации тайла
  • интерполяция на GPU

Ошибка контролируется через:

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

Преимущества и ограничения формата

Сильные стороны:

  • высокая степень сжатия геометрии
  • быстрый стриминг по сети
  • поддержка глобальных моделей Земли
  • эффективная работа с GPU

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

  • зависимость от предвычисленных тайлов
  • сложность генерации серверной стороны
  • ограниченная гибкость динамического изменения рельефа
  • необходимость строгой согласованности LOD-структуры