Визуализация в deck.gl опирается на низкоуровневую графическую модель WebGL, где основная логика рендеринга выполняется на GPU через шейдеры. Шейдеры представляют собой небольшие программы, написанные на GLSL (OpenGL Shading Language), выполняемые параллельно на графическом процессоре.
В deck.gl шейдеры используются не как изолированный слой, а как часть системы слоёв, геометрий и атрибутов. Каждый слой инкапсулирует собственную шейдерную логику, которая комбинируется с базовыми модулями фреймворка.
Шейдеры делятся на два основных типа:
Vertex Shader
Fragment Shader
Внутри deck.gl шейдеры не пишутся «с нуля» для каждого слоя. Используется модульная система:
Шейдер слоя собирается из нескольких источников:
vertexShaderfragmentShadermodulesdefinesinjectsТакой подход позволяет переиспользовать код и избегать дублирования логики между слоями.
Кастомные шейдеры обычно подключаются через Layer или
CompositeLayer.
Ключевые элементы:
attribute — данные вершин (позиции, цвета,
индексы)uniform — глобальные параметры (время, масштаб,
камера)varying — передача данных между vertex и fragment
shaderПример структуры слоя:
import {Layer} from '@deck.gl/core';
class CustomLayer extends Layer {
getShaders() {
return {
vertexShader: VERTEX_SHADER,
fragmentShader: FRAGMENT_SHADER,
modules: ['project32', 'picking']
};
}
}
В deck.gl данные проходят через AttributeManager. Он
автоматически синхронизирует JavaScript-массивы с GPU-буферами.
Типичные атрибуты:
positions — координаты вершинcolors — RGBAindices — индексация геометрииsizes — размеры объектовВ GLSL это выглядит как:
attribute vec3 positions;
attribute vec4 colors;
varying vec4 vColor;
Связь между CPU и GPU полностью управляется фреймворком, что снижает необходимость ручного управления буферами WebGL.
Одна из ключевых задач шейдеров — преобразование координат.
В deck.gl используется многоступенчатая система:
Шейдерная функция проектирования часто выглядит так:
vec4 position_world = modelMatrix * vec4(positions, 1.0);
vec4 position_clip = project_common_position_to_clipspace(position_world);
Модуль project32 или project64 обеспечивает
корректную работу с большими координатами (например, геоданные).
Fragment shader в deck.gl часто отвечает за визуальные эффекты:
Пример:
precision highp float;
varying vec4 vColor;
void main() {
gl_FragColor = vColor;
}
Расширенные эффекты могут учитывать:
deck.gl включает встроенную систему выбора объектов (picking). Она реализуется через специальные шейдерные проходы.
Принцип:
В шейдере:
varying vec3 pickingColor;
void main() {
gl_FragColor = vec4(pickingColor, 1.0);
}
Это позволяет реализовать:
deck.gl использует систему модулей для повторного использования GLSL-кода.
Основные модули:
project32 — 32-битная проекцияproject64 — высокоточная проекцияpicking — логика выбора объектовlighting — освещениеmath — вспомогательные функцииМодули подключаются декларативно:
modules: ['project32', 'picking']
И автоматически внедряются в шейдерный код.
Одной из мощных особенностей является система
inject.
Она позволяет встраивать код в заранее определённые точки шейдера:
vs:#decl — объявления переменныхvs:#main-start — начало vertex shaderfs:#main-end — конец fragment shaderПример:
injects: {
'vs:#main-start': `
vColor.rgb *= 0.5;
`
}
Это позволяет модифицировать поведение слоя без переписывания всей шейдерной программы.
При работе с геоданными возникает проблема точности float32.
deck.gl решает её через:
fp64)Пример GLSL:
vec2 highLowSum(vec2 a, vec2 b);
Модуль project64 позволяет сохранять точность при
масштабах планеты.
Производительность шейдеров зависит от:
Практики оптимизации:
step, smoothstepКаждый слой deck.gl — это:
Шейдеры не существуют отдельно — они часть декларативной модели слоя.
Типичный цикл:
Шейдеры deck.gl позволяют комбинировать:
Пример:
uniform float opacity;
void main() {
gl_FragColor = vec4(vColor.rgb, vColor.a * opacity);
}
Это обеспечивает гибкость при сохранении архитектурной целостности.
Uniform-переменные позволяют передавать динамические данные:
Пример:
uniform float time;
void main() {
float pulse = sin(time);
}
Uniform обновляются на каждом кадре без пересборки шейдера.
Шейдеры определяют не только геометрию, но и визуальный язык:
Гибкость GLSL в deck.gl позволяет строить сложные системы визуализации, где GPU становится основным вычислительным слоем, а JavaScript — управляющим уровнем.