Система расширений в Deck.gl построена как механизм композиции функциональности поверх базовых слоёв без необходимости наследования или модификации исходного класса слоя. Расширение представляет собой модуль, который подключается к слою и динамически добавляет:
Ключевая идея заключается в разделении ответственности: слой отвечает за визуализацию геометрии, расширение — за добавление ортогональной функциональности.
Расширения подключаются через массив extensions в
конфигурации слоя:
new ScatterplotLayer({
id: 'points',
data,
getPosition: d => d.position,
getRadius: d => d.radius,
extensions: [
new DataFilterExtension({filterSize: 1}),
new BrushingExtension()
]
});
Каждое расширение реализует интерфейс, который Deck.gl использует для:
state слоя,props,Расширение в Deck.gl — это объект, который может реализовать набор “хуков”. Эти хуки вызываются в определённые моменты жизненного цикла слоя:
initializeStateupdateStatedrawfinalizeStategetShadersgetUniformsgetAttributesКаждый слой при инициализации агрегирует поведение всех подключённых расширений, формируя единый pipeline рендеринга.
Одной из ключевых возможностей является расширение GLSL-шейдеров. Расширения могут добавлять:
Расширение может внедрять код в шейдерный pipeline:
getShaders() {
return {
modules: [dataFilter, brushing]
};
}
Каждый модуль содержит GLSL-фрагменты:
inject: { 'vs:#decl': '...', 'fs:#main-end': '...' }Таким образом формируется композиция шейдерного кода без ручного редактирования базового слоя.
DataFilterExtension реализует фильтрацию данных на GPU
уровне. Основная задача — исключать элементы до стадии рендеринга,
минимизируя CPU-нагрузку.
Каждый элемент получает дополнительный атрибут фильтра, который сравнивается с заданным диапазоном:
Фильтрация выполняется в шейдере через discard-логику.
new ScatterplotLayer({
data,
getPosition: d => d.position,
extensions: [
new DataFilterExtension({filterSize: 1})
],
getFilterValue: d => d.timestamp,
filterRange: [start, end]
});
filterRange,BrushingExtension используется для интерактивного
выделения объектов в зависимости от расстояния до курсора или центра
взаимодействия.
Каждый объект получает дополнительный атрибут, участвующий в вычислении “distance field”. В шейдере вычисляется расстояние до активной точки взаимодействия.
getBrushingTargetbrushingRadiusbrushingEnabledОбъекты, находящиеся вне радиуса, могут:
Расширение, отвечающее за расширенные стили линий и путей, выходящие
за пределы базового PathLayer.
Расширение переопределяет атрибуты:
instanceWidthsinstanceColorsinstanceTimestampsи модифицирует геометрию линий в шейдере.
MaskExtension реализует геометрическую маскировку слоёв
с использованием масочных слоёв (например, полигонов).
Каждый пиксель проверяется на принадлежность маске через stencil buffer или геометрическое тестирование.
GeoJsonLayer как источником маски.Расширение для работы с рельефом и подстройки визуализации под высотные данные.
TerrainLayer.Каждый объект получает дополнительную трансформацию позиции:
Deck.gl не объединяет расширения последовательно, а строит единый агрегированный слой:
Слой запрашивает список расширений.
Каждое расширение возвращает:
Deck.gl выполняет merge всех модулей.
Формируется единый shader program.
Важный момент: порядок расширений может влиять на результат, особенно при конфликте shader injections.
Расширения могут вмешиваться в состояние слоя через:
state.attributeManager,state.model,state.uniforms.Они могут:
Расширения часто регистрируют дополнительные атрибуты через
AttributeManager:
initializeState() {
const attributeManager = this.getAttributeManager();
attributeManager.addInstanced({
filterValues: {
size: 1,
accessor: 'getFilterValue'
}
});
}
Это позволяет интегрировать новые данные в существующий rendering pipeline без модификации базового слоя.
Каждое расширение может содержать shader module:
export default {
name: 'customExtension',
vs: `
attribute float customValue;
`,
fs: `
float intensity = customValue * 0.5;
`,
inject: {
'vs:#main-end': `
vCustom = customValue;
`
}
};
Модули объединяются через систему препроцессинга shader assembly.
При одновременном использовании нескольких расширений возможны конфликты:
Deck.gl решает это через:
Расширения влияют на performance через:
Критические оптимизации:
Некоторые расширения напрямую связаны с user interaction pipeline:
Например, BrushingExtension зависит от координат курсора
и пересчитывает uniform при каждом frame update.
Deck.gl позволяет создавать собственные расширения, реализуя интерфейс:
initializeStateupdateStatedrawgetShadersfinalizeStateЭто превращает extensions в полноценный слой абстракции, способный:
Комбинация DataFilterExtension и
BrushingExtension позволяет реализовать:
MaskExtension совместно с
PathStyleExtension используется для:
TerrainExtension применяется для: