Viewport culling в Deck.gl представляет собой ключевой механизм оптимизации рендеринга, основанный на исключении объектов, находящихся вне текущей области видимости камеры. В контексте высокопроизводительной визуализации больших наборов данных этот механизм определяет разницу между интерактивным приложением и системой, не справляющейся с нагрузкой даже при умеренном объёме геометрии.
Viewport culling опирается на геометрическое соотношение объектов сцены и текущего состояния камеры. В терминах WebGL-сцены каждый кадр характеризуется параметрами:
Любой объект сцены может быть представлен через ограничивающий объём (bounding volume), чаще всего axis-aligned bounding box (AABB) или bounding sphere. Основная задача culling — определить пересечение этих объёмов с видимой областью (view frustum).
Если объект полностью находится вне фрустума, он исключается из pipeline рендеринга до этапа передачи в GPU.
View frustum представляет собой усечённую пирамиду, задаваемую шестью плоскостями:
Каждая плоскость описывается уравнением:
ax + by + cz + d = 0
Положение точки относительно плоскости определяется знаком выражения:
f(x,y,z) = ax + by + cz + d
Если значение функции для всех вершин bounding volume отрицательно относительно одной из плоскостей, объект считается вне видимости.
В системах типа Deck.gl этот этап выполняется на CPU до передачи данных в WebGL pipeline, что позволяет существенно снизить нагрузку на GPU.
Внутренняя архитектура viewport culling основана на разделении ответственности между слоями (layers), геометрическими источниками данных и системой координат viewport.
Основные этапы:
Каждый слой в Deck.gl реализует собственную стратегию culling, адаптированную под тип данных: точки, линии, полигоны, тайлы.
После применения матрицы модели, вида и проекции (MVP matrix) координаты переводятся в clip space:
v_{clip} = M_{projection} M_{view} M_{model} v
В этом пространстве применяется перспективное деление:
финальная проверка попадания в диапазон видимости:
-1 x,y,z
Любые объекты, выходящие за эти пределы полностью, исключаются из рендеринга.
В системах визуализации существует два основных подхода:
В Deck.gl основной подход — предварительная фильтрация на CPU. Преимущества:
Недостатки:
Альтернативный подход предполагает использование compute shaders или vertex shaders для отсечения. Он применяется реже в Deck.gl из-за архитектурных ограничений WebGL 1/2 и необходимости совместимости.
Viewport culling становится эффективным только при наличии пространственной индексации. В Deck.gl применяются структуры:
Quadtrees особенно эффективны для географических данных, где плотность точек неравномерна. Узлы дерева агрегируют bounding boxes, что позволяет исключать целые группы объектов одним тестом пересечения.
Для больших картографических наборов данных применяется tile-based стратегия. Каждый тайл имеет собственный bounding box, и проверка выполняется на уровне тайлов, а не отдельных объектов.
Псевдологика:
Такой подход особенно важен при работе с миллионами точек или линий.
В дополнение к геометрическому culling применяется screen-space error оценка. Объекты могут быть исключены даже при попадании во фрустум, если их вклад в изображение ниже порога пиксельной значимости.
Метрика:
error =
Если error меньше заданного threshold, объект не рендерится.
Каждый слой в Deck.gl реализует culling на уровне своей абстракции.
Для точечных данных используется bounding box по набору точек. Проверка выполняется батчами, что минимизирует overhead.
Линии разбиваются на сегменты, и каждый сегмент проверяется отдельно. Это позволяет исключать части длинных географических маршрутов.
Полигональные структуры используют convex hull или предварительно вычисленные bounding boxes. Дополнительно применяется тест пересечения с frustum planes.
В сценариях с анимацией или потоковыми данными viewport culling дополняется временной фильтрацией. Объекты могут быть исключены не только по пространству, но и по времени жизни.
Типичный кейс — визуализация треков:
Механизм picking (выбор объектов) тесно связан с viewport culling. При отключённом culling увеличивается пространство поиска для hit-testing. При активном culling уменьшается число кандидатов, что ускоряет интерактивные операции.
Однако чрезмерное агрессивное отсечение может приводить к потере точности при hover-событиях, особенно для объектов на границе frustum.
При больших географических координатах возникает проблема точности float32. Viewport culling должен учитывать:
В Deck.gl используются стратегии floating origin и локализации координат относительно viewport центра, что уменьшает накопление ошибок.
Culling напрямую влияет на количество батчей, отправляемых в GPU. Каждый оставшийся объект после отсечения попадает в render batch.
Оптимизация заключается в:
Таким образом viewport culling становится предшествующим этапом всей графической оптимизации.
В зависимости от zoom level и плотности данных применяются адаптивные стратегии:
Это позволяет поддерживать стабильный frame rate при изменении масштаба сцены.
Математически это можно выразить через функцию зависимости детализации: