MaterialAppearance

В системе рендеринга CesiumJS ключевую роль в формировании внешнего вида геометрии играет механизм Appearance. Он определяет, каким образом вершины, индексы и материалы превращаются в пиксели на экране. MaterialAppearance является одной из наиболее гибких реализаций этого механизма, предоставляя прямую интеграцию с системой материалов и шейдерной моделью Cesium.

MaterialAppearance используется совместно с Primitive и Geometry, формируя связку, в которой геометрия отвечает за форму, а appearance — за визуальное представление. В отличие от более простых вариантов, таких как EllipsoidSurfaceAppearance, MaterialAppearance не ограничен конкретным типом геометрии и рассчитан на универсальное применение.

MaterialAppearance представляет собой слой абстракции над GLSL-шейдерами, автоматически генерируемыми на основе материала (Material) и параметров геометрии. Основная идея заключается в разделении логики:

  • Geometry отвечает за вершины, индексы и атрибуты
  • Material определяет визуальные свойства поверхности
  • Appearance связывает эти части и формирует итоговый shader program

MaterialAppearance не содержит фиксированного шейдера. Вместо этого он динамически компилирует fragment shader на основе описания материала и uniform-параметров.

Базовая структура использования

Типичная связка выглядит следующим образом:

const material = Cesium.Material.fromType("Color");

const appearance = new Cesium.MaterialAppearance({
    material: material,
    faceForward: true,
    translucent: false
});

const primitive = new Cesium.Primitive({
    geometryInstances: new Cesium.GeometryInstance({
        geometry: new Cesium.RectangleGeometry({
            rectangle: Cesium.Rectangle.fromDegrees(-80, 20, -70, 30),
            vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT
        })
    }),
    appearance: appearance
});

viewer.scene.primitives.add(primitive);

В этом примере MaterialAppearance управляет тем, как прямоугольная геометрия будет окрашена и отрисована, используя стандартный материал Color.

Свойство material

Material является центральным элементом системы внешнего вида. Он описывает поведение поверхности через набор uniform-переменных и процедурных функций.

MaterialAppearance принимает объект Material, который может быть:

  • Статическим (цвет, текстура)
  • Процедурным (градиенты, шум)
  • Составным (несколько слоев)

В момент компиляции шейдера Cesium преобразует материал в GLSL-код, который вставляется в fragment pipeline.

Пример использования текстурного материала:

const material = new Cesium.Material({
    fabric: {
        type: "Image",
        uniforms: {
            image: "texture.png"
        }
    }
});

MaterialAppearance затем использует этот материал как источник цвета пикселя.

faceForward и работа с нормалями

Свойство faceForward управляет поведением при рендеринге граней, ориентированных от камеры. При включении:

  • нормали инвертируются для обратных граней
  • освещение вычисляется корректно даже при перевёрнутой геометрии

Это особенно важно для тонких поверхностей, таких как стены или полигоны без объёма.

new Cesium.MaterialAppearance({
    faceForward: true
});

translucent и режим смешивания

Параметр translucent определяет, будет ли поверхность участвовать в alpha blending.

  • true — включается прозрачность и сортировка
  • false — используется opaque pipeline

MaterialAppearance автоматически влияет на выбор render state:

new Cesium.MaterialAppearance({
    translucent: true
});

При включении прозрачности Cesium активирует blending:

  • source alpha
  • destination inverse alpha

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

flat и освещение

Свойство flat отключает освещение на поверхности. В этом режиме:

  • игнорируются нормали
  • результат зависит только от материала
  • отсутствует shading по Ламберту
new Cesium.MaterialAppearance({
    flat: true
});

Flat-режим используется для аналитической визуализации, тепловых карт и 2D-подобных слоёв.

vertexFormat и связь с геометрией

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

  • position
  • normal
  • st (texture coordinates)
  • color

Несовпадение VertexFormat между Geometry и Appearance приводит к некорректному рендерингу.

Пример согласования:

geometry: new Cesium.RectangleGeometry({
    rectangle: rect,
    vertexFormat: Cesium.VertexFormat.ALL
})

MaterialAppearance при этом ожидает наличие соответствующих атрибутов для корректного освещения и текстурирования.

renderState и низкоуровневая настройка

MaterialAppearance позволяет переопределять renderState — набор параметров WebGL контекста:

  • depthTest
  • blending
  • culling
  • polygonOffset

Пример:

new Cesium.MaterialAppearance({
    renderState: {
        depthTest: {
            enabled: true
        },
        cull: {
            enabled: true,
            face: Cesium.CullFace.BACK
        }
    }
});

Эта возможность делает MaterialAppearance инструментом не только визуального уровня, но и управления поведением GPU.

Shaders и генерация кода

MaterialAppearance не хранит статический fragment shader. Вместо этого происходит генерация:

  1. Анализ Material.fabric
  2. Построение GLSL-функций
  3. Вставка uniform-переменных
  4. Комбинация с lighting model
  5. Компиляция program на GPU

Fragment shader включает:

  • функцию получения цвета материала
  • обработку освещения
  • alpha blending
  • дополнительные эффекты (noise, texture sampling)

Vertex shader обычно остаётся стандартным, но может модифицироваться через VertexFormat.

Связь с lighting model

MaterialAppearance поддерживает освещение Cesium, включая:

  • diffuse lighting
  • specular highlights
  • ambient contribution

Если материал не отключает lighting, вычисления выполняются в view space:

  • нормаль трансформируется матрицей normalMatrix
  • направление света берётся из scene context
  • итоговый цвет комбинируется с material color

Производительность и оптимизация

MaterialAppearance является одним из наиболее гибких, но и более дорогих вариантов appearance.

Основные факторы нагрузки:

  • динамическая генерация шейдеров
  • сложные material graphs
  • прозрачность (sorting)
  • высокое число uniform updates

Оптимизационные подходы:

  • использование статических материалов вместо процедурных
  • отключение translucent при отсутствии необходимости
  • минимизация VertexFormat
  • переиспользование Material instances

Комбинирование с несколькими материалами

MaterialAppearance поддерживает сложные материалы через fabric composition:

  • mix
  • composite
  • procedural noise
  • texture blending

Пример комбинированного материала:

const material = new Cesium.Material({
    fabric: {
        type: "Composite",
        materials: {
            base: {
                type: "Color"
            },
            detail: {
                type: "Image",
                uniforms: {
                    image: "detail.png"
                }
            }
        },
        components: {
            diffuse: "base.color * detail.color"
        }
    }
});

MaterialAppearance интерпретирует такую структуру как единый shader pipeline.

Роль в Primitive pipeline

Внутри Primitive pipeline MaterialAppearance выполняет следующие этапы:

  1. Получение GeometryInstance
  2. Подготовка vertex buffers
  3. Генерация shader program
  4. Привязка uniforms из Material
  5. Установка render state
  6. Отправка draw call в WebGL

Таким образом, MaterialAppearance выступает связующим звеном между абстрактной геометрией и низкоуровневым GPU-рендерингом.