Геометрия в CesiumJS формируется на нескольких уровнях абстракции:
Entities → Primitives → GeometryInstance → WebGL
buffers. Основная стоимость производительности возникает не на
этапе рендера, а на этапе подготовки данных: тесселяция, трансформация
координат, генерация индексов и загрузка вершин в GPU.
Ключевые узлы нагрузки:
- генерация вершинной сетки (CPU-bound)
- передача буферов в WebGL (GPU upload)
- избыточная детализация геометрии
- отсутствие батчинга и повторного использования буферов
- неэффективные bounding volumes, приводящие к лишнему рендеру
Оптимизация геометрии в CesiumJS всегда сводится к уменьшению объёма
данных и снижению числа draw calls при сохранении визуальной
точности.
Примитивы
вместо Entities как базовый уровень оптимизации
Entity API удобен для разработки, но создаёт дополнительные накладные
расходы:
- динамическое пересоздание геометрии при изменениях свойств
- дополнительная абстракция над Primitive API
- частые пересчёты матриц и материалов
Primitives работают ближе к WebGL и позволяют:
- повторно использовать GeometryInstance
- минимизировать перерасчёт данных
- объединять объекты в батчи
Типовая замена:
- Entity Polygon →
Primitive + GeometryInstance + PerInstanceColorAppearance
- Entity Polyline →
Primitive + PolylineGeometry
Ключевой принцип: статическая геометрия всегда должна уходить
в Primitive слой.
Батчинг геометрии и
снижение draw calls
Каждый draw call в WebGL — значительная стоимость. CesiumJS позволяет
объединять геометрию через:
GeometryInstance
- единый
Primitive
- общий
Appearance
Пример стратегии:
- множество зданий → один Primitive
- различие задаётся через per-instance attributes
Преимущество:
- один вызов отрисовки вместо сотен
- единый буфер вершин
- кэширование GPU ресурсов
Ограничение:
- одинаковый материал у всех инстансов
Инстансинг и
повторное использование форм
При повторяющейся геометрии (деревья, столбы, здания) применяется
instancing:
- одна базовая геометрия
- трансформации через model matrix
- минимальный объём памяти
Особенно эффективно при:
- городских сценах
- инженерных моделях
- симуляциях инфраструктуры
Ключевой принцип: различия должны быть трансформационными, а
не геометрическими.
Упрощение
полигонов и контроль плотности сетки
Избыточная плотность вершин — один из главных источников деградации
FPS.
Методы оптимизации:
- decimation (сокращение полигонов)
- edge collapse
- removal of collinear points
- adaptive simplification по экранному размеру
Практическое правило:
- детализация должна зависеть от пиксельного размера объекта на
экране
Если объект занимает менее нескольких пикселей — геометрия должна
деградировать до минимального представления.
Использование
Quantized-geometry и сжатых атрибутов
CesiumJS поддерживает оптимизированные форматы хранения вершин:
- quantized positions
- compressed normals
- oct-encoded vectors
Преимущества:
- снижение памяти до 4–8 раз
- уменьшение bandwidth загрузки
- ускорение передачи в GPU
Особенно эффективно в:
- 3D Tiles
- больших CAD-моделях
- глобальных сценах
Draco-сжатие и оптимизация
glTF
Для моделей glTF применяется Draco compression:
- сжатие индексов
- сжатие вершин
- уменьшение веса модели
Плюсы:
- резкое снижение размера ассетов
- ускорение загрузки
Минусы:
- дополнительная CPU-декомпрессия
- увеличение времени первого кадра
Оптимальный подход:
- Draco для статических моделей
- без Draco для часто обновляемой геометрии
3D Tiles как основной
механизм оптимизации
3D Tiles — ключевая система оптимизации больших геометрических
наборов.
Основные механизмы:
- иерархия уровней детализации (LOD)
- пространственное деление (quadtree/octree)
- bounding volumes (sphere, box, region)
- стриминг по экранному пространству
Оптимизационные эффекты:
- загрузка только видимых тайлов
- отказ от полной геометрии сцены
- адаптивная детализация
Критический параметр: screen space error (SSE) Он
управляет балансом между качеством и производительностью.
Контроль видимости и
отсечение геометрии
CesiumJS активно использует:
- frustum culling
- backface culling
- occlusion culling (частично через tilesets)
- clipping planes
Особенно важно:
- правильно задавать bounding volumes
- избегать чрезмерно больших bounding box’ов
- разделять геометрию по логическим регионам
Ошибки в bounding volume приводят к:
- отрисовке невидимых объектов
- перегрузке GPU pipeline
Разделение больших геометрий
Монолитные меши ухудшают производительность:
Проблемы:
- отсутствие LOD
- невозможность culling на уровне частей
- рост времени загрузки
Решение:
- деление по пространству
- деление по типам объектов
- разбиение по уровню детализации
Оптимальная гранулярность:
- объект должен быть достаточно крупным для батчинга
- но достаточно маленьким для отсечения
Оптимизация атрибутов вершин
Каждый дополнительный атрибут увеличивает:
- размер буфера
- время передачи в GPU
- нагрузку на шейдер
Рекомендуется минимальный набор:
- position
- normal (если требуется освещение)
- st (если есть текстуры)
Удаляются:
- неиспользуемые UV-каналы
- лишние tangent/bitangent
- дублирующиеся color attributes
Геометрия и terrain:
clamping и декуплинг
При работе с рельефом Cesium terrain:
- geometry clamped to ground создаёт дополнительные вычисления
- пересчёт высот увеличивает CPU нагрузку
Оптимизации:
- использование precomputed heights
- минимизация dynamic clamping
- переход к baked geometry при статике
Dynamic vs Static геометрия
Ключевое разделение:
Статическая геометрия
- загружается один раз
- не изменяется
- может быть агрессивно оптимизирована
Динамическая геометрия
- требует пересчёта каждый кадр или при изменении камеры
- должна быть максимально облегчена
Практический принцип:
- любая геометрия без анимации или взаимодействия считается
статической
Минимизация
пересчётов и requestRenderMode
CesiumJS работает в режиме постоянного рендера по умолчанию.
Оптимизация:
requestRenderMode = true
- рендер только при изменениях сцены
Эффект:
- снижение CPU нагрузки
- уменьшение энергопотребления
- стабильный FPS в статических сценах
Использование
GeometryPipeline
GeometryPipeline позволяет:
- оптимизировать индексы
- объединять буферы
- вычислять bounding spheres
- трансформировать геометрию перед GPU
Ключевые стадии:
- vertex cache optimization
- index reordering
- normal computation
- bounding computation
Оптимизация полилиний и
кривых
Polyline geometry часто становится узким местом:
Проблемы:
- слишком много сегментов
- высокая плотность точек
Методы оптимизации:
- Douglas–Peucker simplification
- adaptive sampling по экранному расстоянию
- ограничение максимального числа сегментов
GPU-ориентированная
оптимизация геометрии
На уровне GPU важны:
- снижение bandwidth
- уменьшение overdraw
- минимизация state changes
Подходы:
- объединение материалов
- использование одинаковых шейдеров
- сокращение переключений текстур
Баланс точности и
производительности
Оптимизация геометрии в CesiumJS всегда является компромиссом:
- высокая детализация → высокая CPU/GPU нагрузка
- агрессивная оптимизация → потеря визуальной точности
Практический критерий:
- геометрия должна соответствовать экранному разрешению, а не реальной
плотности данных
Избыточная точность вне пределов пиксельной сетки не даёт визуального
выигрыша, но резко увеличивает стоимость рендера.