Culling техники

В WebGL-движках глобальной визуализации критически важна минимизация количества отрисовываемой геометрии. CesiumJS использует многоуровневую систему отсечения (culling), сочетающую геометрическое, пространственное и экранное отбрасывание объектов до стадии рендеринга.

Отсечение в CesiumJS строится вокруг нескольких ключевых уровней:

  • отсечение по усечённой пирамиде видимости (view frustum culling)
  • отсечение по глубине и перекрытию (depth/occlusion culling)
  • отсечение по уровню детализации (LOD culling)
  • отсечение по экранному размеру (screen space error culling)
  • пользовательские механизмы скрытия объектов

Эти механизмы работают совместно и формируют каскадную фильтрацию сцены.


Frustum Culling и геометрические объёмы

Основной этап отсечения выполняется через проверку попадания bounding volumes в усечённую пирамиду камеры.

Cesium использует несколько типов ограничивающих объёмов:

  • BoundingSphere
  • AxisAlignedBoundingBox (AABB)
  • OrientedBoundingBox (OBB)

Каждый кадр камера формирует CullingVolume, представляющий шесть плоскостей:

  • left
  • right
  • top
  • bottom
  • near
  • far

Проверка выполняется для каждого объекта сцены:

  • если bounding volume полностью вне одной плоскости → объект отбрасывается
  • если пересекает → объект проходит дальше по пайплайну
  • если внутри → объект отправляется на рендер или дальнейший LOD-анализ

Ключевой оптимизацией является использование сферических bounds для быстрых проверок:

distance(camera, center) > radius → cull

Сферы дешевле в вычислении, поэтому используются как первичный фильтр.


Hierarchical Culling в 3D Tiles

В случае работы с 3D Tiles основная нагрузка приходится на дерево тайлов (Cesium3DTileset). Отсечение выполняется на уровне узлов дерева.

Каждый тайл содержит:

  • bounding volume
  • geometric error
  • ссылки на дочерние тайлы
  • контент (модель, батч, геометрия)

Алгоритм проходит по дереву сверху вниз:

  1. проверка bounding volume относительно frustum
  2. оценка screen space error
  3. решение о subdivide или render

Если узел не проходит frustum test — все дочерние узлы автоматически исключаются без проверки.

Это называется hierarchical culling by bounds propagation.


Screen Space Error как форма интеллектуального отсечения

Одним из ключевых механизмов является screen space error (SSE). Он определяет, насколько сильно геометрия “теряет качество” при текущем масштабе экрана.

Формально оценивается как проекция геометрической ошибки на экран:

  • чем ближе камера → SSE растёт
  • чем дальше камера → SSE падает

Если SSE меньше заданного порога (maximumScreenSpaceError), тайл не subdivide-ится и остальные ветви дерева отсекаются.

Таким образом, culling происходит не только по видимости, но и по “достаточности детализации”.


Backface Culling и ориентация треугольников

На уровне WebGL применяется классическое отсечение обратных граней:

  • front-face определяется winding order (CW/CCW)
  • задние грани отбрасываются на GPU

В CesiumJS это управляется через материалы и настройку WebGL контекста:

  • cullFace: true
  • frontFace: CCW

Backface culling особенно важен для:

  • terrain meshes
  • extruded polygons
  • building geometries

При неправильной топологии отключение culling может привести к двойной отрисовке и падению производительности.


Occlusion Culling и глубинное отсечение

В отличие от классического frustum culling, occlusion culling учитывает перекрытие объектов другими геометриями.

CesiumJS не использует полноценный GPU occlusion query для всех объектов, но применяет приближённые методы:

  • depth buffer tests
  • hierarchical z-culling в рамках tileset traversal
  • bounding volume depth estimation

Особенно эффективно это работает с:

  • городскими сценами
  • плотными 3D Tiles зданиями
  • terrain + photogrammetry

Дополнительно используется:

  • gl.depthTest на уровне материалов
  • globe.depthTestAgainstTerrain

Последний параметр позволяет скрывать объекты, находящиеся под рельефом.


Culling на уровне глобуса

Гео-глобус в CesiumJS сам по себе является источником отсечения:

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

Алгоритм включает:

  • проверку угла между камерой и нормалью поверхности
  • отсечение тайлов, находящихся за кривизной Земли
  • учет высоты камеры

Это позволяет игнорировать огромные сегменты планеты без дополнительных вычислений.


Distance-based culling

Дополнительный слой отсечения основан на расстоянии до камеры.

Применяется для:

  • billboards
  • labels
  • point clouds
  • мелких primitives

Основные критерии:

  • максимальная дистанция отображения (distanceDisplayCondition)
  • минимальный экранный размер
  • плотность точек

Пример логики:

  • если объект меньше 1–2 пикселей → исключается
  • если расстояние > threshold → исключается

Этот механизм особенно важен для предотвращения визуального шума при глобальном обзоре.


Primitive-level culling

Каждый primitive в Cesium проходит собственный pipeline отсечения:

  • geometry culling
  • material visibility check
  • render state validation

Ключевые типы primitives:

  • Primitive
  • GroundPrimitive
  • ClassificationPrimitive
  • Model

Для каждого применяется свой набор bounding volumes и стратегий проверки.

Особое внимание уделяется GroundPrimitive, так как он должен учитывать рельеф и пересечения с terrain.


Classification и специализированное отсечение

Classification primitives используют отдельный pipeline, где отсечение происходит не только по видимости, но и по типу поверхности:

  • terrain classification
  • 3D Tiles classification

В этом режиме объект может быть “видим”, но исключён из рендера, если не соответствует типу классификации.

Это добавляет дополнительный уровень логического culling.


Skip Levels of Detail и оптимизация обхода дерева

В больших tileset структурах применяется:

  • skipLevelOfDetail
  • immediatelyLoadDesiredLevelOfDetail
  • loadSiblings

Эти параметры влияют на culling traversal:

  • пропуск промежуточных уровней дерева
  • ускоренное отсечение невидимых узлов
  • уменьшение количества проверок bounding volume

В результате уменьшается CPU overhead на сценах с миллионами тайлов.


GPU и CPU разделение ответственности

Culling в CesiumJS разделён между CPU и GPU:

CPU-уровень:

  • traversal tileset tree
  • frustum checks
  • SSE evaluation
  • bounding volume tests

GPU-уровень:

  • backface culling
  • depth testing
  • fragment rejection
  • z-buffer occlusion

Такое разделение снижает нагрузку на JavaScript и обеспечивает масштабируемость.


Практические аспекты производительности culling

Эффективность системы отсечения зависит от:

  • качества bounding volumes
  • глубины tileset дерева
  • плотности геометрии
  • параметров камеры
  • настроек LOD

Наиболее критичные узлы оптимизации:

  • уменьшение количества draw calls через раннее отсечение
  • корректные bounding sphere вместо AABB там, где возможно
  • агрессивное SSE culling для дальних объектов
  • настройка maximumScreenSpaceError

Иерархическая координация всех типов отсечения

Все виды culling в CesiumJS работают как единая система:

  1. frustum culling отсеивает полностью невидимые объекты
  2. tileset traversal сокращает дерево данных
  3. SSE culling отсекает лишнюю детализацию
  4. distance culling убирает мелкие объекты
  5. GPU culling завершает фильтрацию на уровне пикселей

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