GeometryInstance

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

GeometryInstance представляет собой контейнер, объединяющий:

  • геометрию (Geometry)
  • матрицу преобразования (modelMatrix)
  • идентификатор (id)
  • дополнительные атрибуты (attributes)
  • параметры классификации и выборки (classificationType, pickability)

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


Архитектурная роль GeometryInstance

В CesiumJS существует три уровня абстракции:

  1. Entity API — высокоуровневое декларативное описание объектов сцены
  2. Primitive API — низкоуровневое управление графическими примитивами
  3. Geometry/GeometryInstance — фундаментальный уровень описания геометрии и её экземпляров

GeometryInstance находится между геометрией и примитивами, позволяя:

  • переиспользовать одну геометрию для множества объектов
  • объединять инстансы в один GPU-буфер
  • уменьшать количество draw calls
  • повышать производительность при массовом рендеринге

Базовая структура GeometryInstance

Типичная структура экземпляра:

const instance = new Cesium.GeometryInstance({
    geometry: new Cesium.BoxGeometry({
        vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
        maximum: new Cesium.Cartesian3(2500000.0, 2500000.0, 2500000.0),
        minimum: new Cesium.Cartesian3(-2500000.0, -2500000.0, -2500000.0)
    }),
    modelMatrix: Cesium.Matrix4.IDENTITY,
    id: "box-1",
    attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(
            Cesium.Color.RED.withAlpha(0.8)
        )
    }
});

Геометрия внутри GeometryInstance

Поле geometry определяет форму объекта. Используются специализированные классы:

  • BoxGeometry
  • SphereGeometry
  • EllipseGeometry
  • RectangleGeometry
  • PolygonGeometry
  • CorridorGeometry
  • WallGeometry
  • PolylineGeometry

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

Ключевое правило: Geometry отвечает за форму, GeometryInstance — за экземпляр и его поведение в сцене.


modelMatrix и трансформации

modelMatrix задаёт преобразование экземпляра в мировом пространстве:

  • перенос (translation)
  • вращение (rotation)
  • масштаб (scale)
const modelMatrix = Cesium.Matrix4.fromTranslation(
    Cesium.Cartesian3.fromDegrees(30.0, 60.0, 1000.0)
);

При использовании GeometryInstance одна и та же геометрия может быть размещена в разных точках мира без пересоздания буферов.


Атрибуты экземпляра (Per-instance attributes)

Одной из наиболее мощных возможностей является система атрибутов.

Цветовые атрибуты

attributes: {
    color: Cesium.ColorGeometryInstanceAttribute.fromColor(
        Cesium.Color.BLUE
    )
}

Атрибуты позволяют задавать уникальные параметры для каждого экземпляра:

  • цвет
  • прозрачность
  • выделение
  • пользовательские параметры

Идентификатор (id)

Поле id используется для:

  • идентификации объекта при picking
  • связывания с внешними данными
  • обработки событий клика
id: {
    name: "Building A",
    height: 120,
    type: "office"
}

При выборе объекта через scene.pick возвращается этот идентификатор, что позволяет связать графику с бизнес-логикой.


GeometryInstance и Primitive

GeometryInstance не используется самостоятельно. Он передаётся в Primitive:

const primitive = new Cesium.Primitive({
    geometryInstances: [instance],
    appearance: new Cesium.PerInstanceColorAppearance({
        translucent: true
    }),
    asynchronous: false
});

Primitive выполняет:

  • объединение нескольких GeometryInstance
  • создание GPU-буферов
  • рендеринг через WebGL
  • управление appearance

Батчинг и производительность

Основная причина использования GeometryInstance — batching.

Без инстансинга:

  • каждый объект = отдельный draw call
  • высокая нагрузка на CPU
  • деградация FPS при тысячах объектов

С GeometryInstance:

  • множество объектов объединяются в один буфер
  • один draw call для десятков/сотен тысяч примитивов
  • минимизация CPU overhead

Appearance и разделение геометрии и визуализации

GeometryInstance отделяет форму от внешнего вида. Внешний вид задаётся через Appearance:

  • PerInstanceColorAppearance
  • MaterialAppearance
  • EllipsoidSurfaceAppearance
  • PolylineMaterialAppearance

Пример:

appearance: new Cesium.PerInstanceColorAppearance({
    translucent: false,
    closed: true
})

Это позволяет использовать одну геометрию с разными визуальными стилями.


Классификация (ClassificationType)

GeometryInstance может использоваться для классификации:

classificationType: Cesium.ClassificationType.TERRAIN

Возможные режимы:

  • TERRAIN — классификация поверхности земли
  • 3D_TILE — классификация 3D Tiles
  • BOTH — комбинированный режим

Используется для:

  • подсветки территории
  • наложения аналитических слоёв
  • скрытия/выделения объектов

Pick и взаимодействие

При включённой поддержке picking каждый GeometryInstance может возвращаться как результат выбора:

const picked = scene.pick(windowPosition);
console.log(picked.id);

Это делает возможным:

  • интерактивные карты
  • выбор зданий
  • аналитические панели
  • связывание с внешними системами

Использование нескольких GeometryInstance

Несколько экземпляров объединяются в один Primitive:

const instances = [
    new Cesium.GeometryInstance({ ... }),
    new Cesium.GeometryInstance({ ... }),
    new Cesium.GeometryInstance({ ... })
];

Преимущества:

  • единый draw call
  • общий appearance
  • централизованное управление

Особенности работы с памятью

GeometryInstance влияет на:

  • размер GPU буферов
  • количество вершин
  • количество атрибутов

Оптимизационные правила:

  • минимизировать уникальные геометрии
  • использовать повторяющиеся instance вместо копий
  • избегать избыточных attributes
  • группировать одинаковые appearance

Различие GeometryInstance и Entity API

Entity API:

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

GeometryInstance:

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

Ключевое различие:

  • Entity → декларативная модель сцены
  • GeometryInstance → графический инстансинг на GPU уровне

Применение в массовом рендеринге

GeometryInstance используется в сценариях:

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

При корректной архитектуре позволяет рендерить сотни тысяч объектов без значительной потери производительности.


Ограничения модели

Несмотря на гибкость, существуют ограничения:

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

Эти ограничения компенсируются высокой скоростью рендеринга и предсказуемостью поведения.


Связь с WebGL pipeline

GeometryInstance напрямую участвует в pipeline:

  1. CPU формирует GeometryInstance
  2. Primitive объединяет данные
  3. WebGL buffers загружаются в GPU
  4. Vertex shader обрабатывает модельные матрицы
  5. Fragment shader применяет appearance
  6. Rasterization формирует финальное изображение

Эта цепочка делает GeometryInstance ключевым звеном между геометрическим описанием и GPU-рендерингом.