В 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 определяет, какие атрибуты доступны в шейдере:
- позиции
- нормали
- 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
Пример логики работы
- Geometry предоставляет позицию и UV
- Material генерирует GLSL фрагмент
- Appearance объединяет shader stages
- создаётся 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
Связка работает следующим образом:
- GeometryInstance создаёт vertex buffers
- Primitive агрегирует экземпляры
- Appearance генерирует shader program
- Cesium создаёт DrawCommand
- 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.
Избыточные атрибуты увеличивают 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