Альфа-канал и прозрачность

Альфа-канал в CesiumJS определяет степень прозрачности практически всех визуальных слоёв сцены: от глобуса и подложки до 3D Tiles, примитивов, материалов и постобработки. Работа с прозрачностью в трёхмерной геопространственной среде требует учёта порядка отрисовки, глубинного буфера, смешивания пикселей и особенностей WebGL-рендера, на котором основан движок.


В CesiumJS прозрачность реализуется через стандартный механизм альфа-смешивания (alpha blending), где каждый пиксель содержит компоненту RGBA, а альфа-значение определяет его вклад в итоговое изображение.

Ключевой принцип:

  • alpha = 1.0 — полностью непрозрачный пиксель
  • alpha = 0.0 — полностью прозрачный пиксель
  • значения между ними формируют полупрозрачность

Однако в трёхмерной сцене этого недостаточно. Важную роль играет порядок отрисовки (render order), буфер глубины (depth buffer) и правила смешивания (blend functions).

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


Прозрачность глобуса (Globe transparency)

Глобус является базовым элементом сцены и управляется объектом scene.globe.

Основные параметры:

  • globe.translucency.enabled
  • globe.opacity
  • globe.baseColor

Включение прозрачности глобуса

viewer.scene.globe.translucency.enabled = true;
viewer.scene.globe.translucency.frontFaceAlpha = 0.5;
viewer.scene.globe.translucency.backFaceAlpha = 0.2;

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

Управление общей непрозрачностью

viewer.scene.globe.opacity = 0.6;

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


Цвет глобуса и альфа-компонента

viewer.scene.globe.baseColor = Cesium.Color.WHITE.withAlpha(0.3);

Базовый цвет влияет на области, где отсутствуют текстуры или данные. Альфа-канал здесь определяет, насколько «сквозным» будет фон.


Прозрачность слоёв Imagery

Слои изображений управляются через ImageryLayer. Каждый слой может иметь собственный коэффициент прозрачности.

const layer = viewer.imageryLayers.addImageryProvider(
    new Cesium.IonImageryProvider({ assetId: 2 })
);

layer.alpha = 0.4;

Смешивание нескольких слоёв

При наложении нескольких imagery-слоёв применяется последовательное альфа-смешивание:

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

Важно учитывать порядок слоёв:

viewer.imageryLayers.raise(layer);
viewer.imageryLayers.lower(layer);

Прозрачные материалы (Material system)

Материалы в CesiumJS часто используются в примитивах (primitives), полигонах и стенах.

Пример материала с альфа-каналом

const material = new Cesium.Material({
    fabric: {
        type: 'Color',
        uniforms: {
            color: Cesium.Color.RED.withAlpha(0.5)
        }
    }
});

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


Прозрачные полигоны и depth masking

При работе с полигонами возникает проблема «самозатенения» и неправильного наложения прозрачных поверхностей.

CesiumJS использует:

  • depth test (проверка глубины)
  • depth mask (запись в буфер глубины)
  • blending (смешивание)

Отключение записи глубины

const appearance = new Cesium.PerInstanceColorAppearance({
    translucent: true,
    closed: true
});

При translucent: true движок переключает режим рендеринга на прозрачный пайплайн.


Прозрачность 3D Tiles

3D Tiles — один из самых сложных случаев, так как содержит иерархические структуры и батчи.

Управление прозрачностью через style

tileset.style = new Cesium.Cesium3DTileStyle({
    color: "color('white', 0.5)"
});

Альфа-канал влияет на каждый тайл индивидуально.

Глобальная прозрачность tileset

tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.MIX;
tileset.colorBlendAmount = 0.5;

Режим MIX позволяет смешивать исходные цвета модели с заданным цветом и альфа-значением.


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

В 3D сценах отсутствует идеальная сортировка по глубине для полупрозрачных объектов. CesiumJS решает это частично через:

  • разделение opaque и translucent pass
  • сортировку по расстоянию до камеры
  • batching прозрачных примитивов

Типичные артефакты:

  • «просвечивание» ближних объектов через дальние
  • неправильное наложение пересекающихся полигонов
  • flickering при движении камеры

Постобработка прозрачности

Post-process эффекты могут изменять восприятие альфа-канала, не изменяя саму геометрию.

Пример:

viewer.scene.postProcessStages.fxaa.enabled = true;

Хотя FXAA не управляет прозрачностью напрямую, он сглаживает границы, что влияет на восприятие полупрозрачных объектов.

Можно также использовать пользовательские шейдеры:

const stage = new Cesium.PostProcessStage({
    fragmentShader: `
        uniform sampler2D colorTexture;
        in vec2 v_textureCoordinates;

        void main() {
            vec4 color = texture(colorTexture, v_textureCoordinates);
            color.a *= 0.5;
            out_FragColor = color;
        }
    `
});

Прозрачность и terrain (рельеф)

Рельеф влияет на восприятие прозрачности из-за пересечений геометрии.

viewer.scene.terrainProvider = Cesium.createWorldTerrain();

При наложении прозрачных объектов на terrain важно учитывать:

  • z-fighting (конфликт глубины)
  • offset геометрии
  • clamping к поверхности

Clipping planes и прозрачность

Clipping planes часто используются совместно с альфа-каналом для «разрезания» сцены.

const clippingPlane = new Cesium.ClippingPlane(
    new Cesium.Cartesian3(0.0, 0.0, -1.0),
    100.0
);

viewer.scene.globe.clippingPlanes = new Cesium.ClippingPlaneCollection({
    planes: [clippingPlane]
});

Хотя clipping не является прозрачностью напрямую, визуально создаёт эффект «обрезанной» прозрачной структуры.


Полупрозрачные линии и полилинии

Polyline в CesiumJS поддерживает альфа-канал через цвет:

viewer.entities.add({
    polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray([
            30, 10,
            40, 40
        ]),
        width: 5,
        material: Cesium.Color.BLUE.withAlpha(0.3)
    }
});

При этом важно учитывать, что линии рендерятся без глубинного объёма, что может приводить к визуальному наложению.


Прозрачность billboards и labels

2D-элементы, размещённые в 3D пространстве, также используют альфа-канал.

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(30, 40),
    billboard: {
        image: 'marker.png',
        color: Cesium.Color.WHITE.withAlpha(0.5)
    }
});

Для текста:

label: {
    text: 'Point',
    fillColor: Cesium.Color.YELLOW.withAlpha(0.7)
}

Оптимизация работы с прозрачностью

Прозрачность — одна из самых дорогих операций в рендеринге.

Основные рекомендации на уровне движка:

  • минимизировать количество перекрывающихся translucent-объектов
  • избегать лишних пересчётов материалов
  • использовать opaque режим там, где возможно
  • группировать прозрачные объекты

CesiumJS автоматически разделяет сцены на passes, но сложные сцены всё равно могут снижать FPS при высокой доле прозрачных объектов.


Особенности взаимодействия alpha и HDR/тон-маппинга

При использовании HDR-рендеринга альфа-канал может восприниматься иначе:

  • яркость фона влияет на видимую прозрачность
  • тон-маппинг изменяет границы смешивания
  • полутона становятся более «мягкими»

Это особенно заметно при ночных режимах карты и космических видах сцены.


Итоговая модель прозрачности в сцене CesiumJS

Вся система альфа-канала складывается из нескольких уровней:

  • глобус (terrain + baseColor + opacity)
  • imagery layers (alpha per layer)
  • entities (color alpha)
  • primitives (material alpha)
  • 3D Tiles (style alpha + blend mode)
  • post-processing (визуальная коррекция)

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