Appearance система

В CesiumJS визуализация геометрии строится через разделение двух уровней: Geometry и Appearance. Геометрия определяет форму объекта и его вершинные данные, тогда как Appearance отвечает за способ отображения этой геометрии — шейдеры, материалы, режимы отрисовки и параметры WebGL pipeline.

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


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

Система Appearance в CesiumJS является прослойкой между низкоуровневым WebGL и высокоуровневыми примитивами сцены.

Каждый объект, добавляемый через Primitive, состоит из двух ключевых компонентов:

  • GeometryInstance — описывает форму, атрибуты и данные вершин
  • Appearance — определяет, как эти данные будут интерпретироваться в шейдере

Основные задачи Appearance:

  • генерация и управление шейдерным кодом
  • определение vertexFormat (какие атрибуты используются)
  • настройка renderState WebGL
  • управление материалами (Material)
  • передача uniform-параметров в шейдер

Базовый контракт Appearance

Все реализации Appearance в CesiumJS следуют единому интерфейсу:

  • vertexShaderSource
  • fragmentShaderSource
  • renderState
  • material
  • translucent
  • closed
  • vertexFormat
  • getFragmentShaderSource()
  • createCommand()

Ключевое свойство — совместимость vertexFormat с Geometry. Несовпадение приводит к некорректной интерпретации буферов вершин.


VertexFormat как основа рендеринга

VertexFormat определяет, какие атрибуты доступны в шейдере:

  • позиции
  • нормали
  • UV координаты
  • цвета
  • тангенты и бинормали

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

  • Geometry может содержать только позиции
  • Appearance может требовать нормали и UV
  • Cesium автоматически формирует pipeline атрибутов

VertexFormat влияет на производительность: чем больше атрибутов — тем больше память и bandwidth GPU.


Material система внутри Appearance

Material в CesiumJS — это отдельная абстракция, встроенная в Appearance. Она определяет визуальное поведение поверхности:

  • цвет
  • текстуры
  • процедурные эффекты
  • анимации шейдеров

Material подключается через Material.fromType() или вручную через uniforms.

Типичная структура:

  • type: имя материала
  • uniforms: параметры
  • shaderSource: GLSL код

Материалы компилируются в часть fragment shader, которую Appearance объединяет с базовым кодом.


MaterialAppearance

Назначение

MaterialAppearance — универсальный Appearance для поверхностей, поддерживающих произвольные материалы.

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

  • полигонов
  • extruded shapes
  • surface geometry
  • terrain-like объектов

Особенности

  • поддерживает любые Material
  • требует нормалей и UV при необходимости
  • автоматически интегрирует material shader code

Пример логики работы

  1. Geometry предоставляет позицию и UV
  2. Material генерирует GLSL фрагмент
  3. Appearance объединяет shader stages
  4. создаётся WebGL draw command

PerInstanceColorAppearance

Назначение

Оптимизированный Appearance для рендеринга множества экземпляров с индивидуальными цветами.

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

  • инстансированных примитивов
  • точечных облаков
  • батчинга объектов

Ключевая особенность

Каждый GeometryInstance может иметь:

  • color attribute
  • уникальные per-instance параметры

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

  • минимальный overhead shader logic
  • высокая производительность batching
  • отсутствие сложных материалов

Ограничения

  • ограниченная визуальная гибкость
  • отсутствие сложных текстурных эффектов

EllipsoidSurfaceAppearance

Назначение

Специализированный Appearance для поверхностей, лежащих на эллипсоиде (модели Земли).

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

  • картографических поверхностей
  • географических слоёв
  • накладываемых данных

Особенности

  • учитывает curvature ellipsoid
  • корректная интерполяция в географических координатах
  • поддержка depth testing с terrain

Внутренняя логика

Shader выполняет преобразование:

  • cartesian → ellipsoid surface projection
  • корректировка z-fighting
  • адаптация под globe curvature

PolylineMaterialAppearance

Назначение

Appearance для полилиний с поддержкой материалов.

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

  • маршрутов
  • траекторий
  • географических линий
  • анимационных потоков

Особенности

  • материал применяется вдоль линии
  • поддержка ширины линии в пикселях
  • экранно-зависимая отрисовка

Ограничения WebGL

Polyline рендеринг зависит от:

  • поддержки line width (ограничена в WebGL)
  • треугольной буферизации линий (Cesium triangulates lines)

Шейдерная архитектура Appearance

Каждый Appearance генерирует два основных шейдера:

Vertex Shader

Отвечает за:

  • преобразование координат
  • применение model-view-projection matrix
  • вычисление varyings

Типичные операции:

  • model → world transform
  • world → eye space
  • projection to clip space

Fragment Shader

Отвечает за:

  • вычисление цвета пикселя
  • применение материалов
  • освещение (если используется)
  • прозрачность

Material system инжектируется именно сюда.


RenderState и управление WebGL pipeline

RenderState внутри Appearance описывает состояние WebGL контекста:

  • blending
  • depth test
  • culling
  • stencil
  • scissor test

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

  • opaque geometry → depth test ON, blending OFF
  • translucent geometry → blending ON
  • terrain overlays → depth mask configurable

RenderState позволяет Appearance управлять GPU pipeline без прямого доступа к WebGL API.


Комбинация Geometry + Appearance

Связка работает следующим образом:

  1. GeometryInstance создаёт vertex buffers
  2. Primitive агрегирует экземпляры
  3. Appearance генерирует shader program
  4. Cesium создаёт DrawCommand
  5. FrameState исполняет команду

Разделение позволяет:

  • переиспользовать геометрию
  • менять визуализацию без пересборки данных
  • оптимизировать batch rendering

Компиляция shader pipeline

При создании Appearance происходит несколько стадий:

1. Shader assembly

  • базовый Cesium shader
  • вставка material GLSL
  • добавление defines

2. Preprocessing

  • подстановка vertexFormat flags
  • оптимизация varyings

3. WebGL program compilation

  • link vertex + fragment shader
  • validation pipeline

4. Caching

  • reuse identical shader programs
  • reduce compilation overhead

Translucency model

Appearance управляет прозрачностью через свойство translucent.

Правила:

  • true → blending enabled
  • false → opaque render queue
  • mixed modes → split rendering passes

Система учитывает:

  • depth sorting
  • order-independent transparency limitations WebGL

Closed geometry флаг

Свойство closed определяет, замкнута ли поверхность:

  • влияет на backface culling
  • изменяет нормали
  • влияет на lighting calculations

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

  • сфер
  • полигонов
  • extruded shapes

Производительность Appearance

Ключевые факторы производительности:

Количество shader permutations

Каждый Appearance может генерировать уникальный shader variant.

VertexFormat минимизация

Избыточные атрибуты увеличивают bandwidth GPU.

Material complexity

Процедурные материалы дороже текстурных.

Batch rendering

PerInstanceColorAppearance наиболее эффективен для массовых объектов.


Кастомные Appearance

CesiumJS позволяет создавать собственные Appearance через реализацию интерфейса:

  • define vertex shader
  • define fragment shader
  • manage renderState
  • implement getFragmentShaderSource()

Типичный сценарий:

  • кастомная визуализация данных
  • научные визуализации
  • нестандартные эффекты (heatmaps, distortion fields)

Взаимодействие с Primitive API

Appearance не используется напрямую в Scene Graph, а привязывается к:

  • Primitive
  • GroundPrimitive
  • ClassificationPrimitive

Primitive выполняет роль контейнера, Appearance — визуального интерпретатора.


Особенности интеграции с Material системой Cesium

Material может:

  • модифицировать diffuse color
  • изменять alpha
  • добавлять procedural noise
  • использовать time uniform для анимации

Appearance обеспечивает binding:

  • material uniforms → shader uniforms
  • material GLSL → fragment shader injection

Ограничения системы Appearance

  • зависимость от WebGL 1/2 возможностей
  • ограниченная динамическая компиляция shader на runtime
  • сложности с order-independent transparency
  • ограничения line rendering в WebGL
  • высокая стоимость кастомных shader permutations