Визуальная сцена в CesiumJS строится вокруг камеры, которая определяет область видимости — усечённую пирамиду (frustum). Эта геометрическая фигура задаётся шестью плоскостями:
Любой объект сцены, находящийся вне этой области, не должен участвовать в рендеринге. Это базовый механизм оптимизации, позволяющий резко снизить количество отрисовываемых сущностей.
= {x ^3 }
В контексте CesiumJS frustum culling выполняет первичную фильтрацию объектов до стадии растеризации.
Frustum задаётся матрицей проекции камеры:
M_{clip} = P V
где:
Из этой матрицы извлекаются плоскости отсечения. CesiumJS строит их автоматически при каждом изменении камеры.
Каждая плоскость описывается уравнением:
ax + by + cz + d = 0
Точка считается видимой, если она находится по «правильную сторону» всех шести плоскостей.
CesiumJS не проверяет каждый вершину объекта напрямую. Вместо этого используются ограничивающие объёмы:
Проверка сводится к тесту пересечения bounding volume с frustum.
Если объём полностью вне фрустума — объект отбрасывается.
Если пересекает — выполняется более детальная проверка или рендеринг.
Внутренний pipeline включает несколько уровней:
CPU frustum culling
Tile-based culling (3D Tiles)
GPU clipping
Основной механизм оптимизации в CesiumJS связан с системой 3D Tiles.
Каждый тайл содержит:
Если bounding volume тайла не пересекает frustum, весь поддеревo исключается.
Это позволяет уменьшить сложность с:
O(n) O(n)
при обходе сцены.
Frustum пересчитывается при каждом изменении камеры:
В CesiumJS это происходит через Scene и
Camera:
const viewer = new Cesium.Viewer("cesiumContainer");
viewer.scene.preRender.addEventListener(() => {
const frustum = viewer.camera.frustum;
});
Изменение параметров камеры напрямую влияет на плоскости отсечения, что вызывает перерасчёт видимости объектов.
Frustum culling тесно связан с LOD-системой:
CesiumJS использует геометрическую ошибку (geometric error), чтобы определить необходимость подгрузки более детальных тайлов.
Один из наиболее частых тестов — sphere-frustum intersection.
Алгоритм:
Если расстояние меньше отрицательного радиуса — объект вне зоны видимости.
Frustum culling влияет на:
В сценах с глобусом без отсечения количество объектов может достигать миллионов, что делает рендеринг невозможным в реальном времени.
CesiumJS снижает нагрузку за счёт:
После CPU-фильтрации включается GPU этап:
Clip space задаётся:
x_{ndc} =
Это финальный этап, который гарантирует корректное отображение геометрии даже при частичном пересечении frustum.
CesiumJS предоставляет инструменты для управления отсечением:
viewer.scene.globe.depthTestAgainstTerrain = true;
viewer.scene.globe.maximumScreenSpaceError = 2;
Также можно влиять на поведение камеры:
viewer.camera.frustum.fov = Cesium.Math.toRadians(60);
viewer.camera.frustum.near = 1.0;
viewer.camera.frustum.far = 10000000.0;
Изменение этих параметров влияет на объём frustum и, следовательно, на количество отсекаемых объектов.
В отличие от классических 3D-движков, CesiumJS работает с эллипсоидом Земли:
Из-за кривизны Земли многие объекты, формально вне прямого frustum, могут частично оставаться видимыми через геометрию поверхности.
Scene graph CesiumJS строится так, что каждый узел имеет bounding volume.
Алгоритм обхода:
Это обеспечивает стабильную производительность даже при сложных сценах с 3D Tiles, моделями и terrain.