Текстура в WebGL представляет собой изображение, которое
накладывается на геометрию для придания визуальной детализации. В
контексте Deck.gl текстуры используются в слоях (layers)
для отрисовки иконок, растровых данных, пользовательских маркеров,
тайлов и сложных визуальных элементов.
Ключевая особенность работы с текстурами заключается в том, что GPU
не может напрямую использовать произвольные изображения без
предварительной загрузки, декодирования и передачи в виде
WebGLTexture. Этот процесс требует строгого контроля над
форматом, размером и состоянием данных.
Первый этап работы с текстурами — получение изображения из внешнего источника. В браузере это может быть:
Типовой механизм загрузки в экосистеме Deck.gl опирается на утилиты
из loaders.gl, где изображение декодируется и приводится к
формату, совместимому с WebGL.
import { loadImage } from '@loaders.gl/images';
async function loadTextureImage(url) {
const image = await loadImage(url);
return image; // HTMLImageElement или ImageBitmap
}
Важный аспект — асинхронность. Текстура не может быть создана до завершения загрузки и декодирования изображения.
После получения изображения оно преобразуется в GPU-ресурс. В Deck.gl это происходит внутри слоя, однако понимание низкоуровневого процесса критично для контроля производительности.
function createTexture(gl, image) {
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
gl.RGBA,
gl.UNSIGNED_BYTE,
image
);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.bindTexture(gl.TEXTURE_2D, null);
return texture;
}
При создании текстуры важны параметры фильтрации и упаковки:
TEXTURE_MIN_FILTER — поведение при уменьшенииTEXTURE_MAG_FILTER — поведение при увеличенииLINEAR обеспечивает сглаживаниеИсторически WebGL накладывает ограничения на размеры текстур. Хотя современные реализации поддерживают NPOT (non-power-of-two), остаются ограничения:
REPEAT) требуют
power-of-twoРекомендуемая практика — использование текстур с размерами 2ⁿ × 2ⁿ при сложных сценах.
Deck.gl инкапсулирует WebGL-логику, предоставляя высокоуровневые слои. Текстуры применяются через свойства слоёв, таких как:
IconLayerBitmapLayerTileLayerLayer реализацииОдин из наиболее эффективных способов работы с текстурами — использование атласа иконок.
import { IconLayer } from '@deck.gl/layers';
const layer = new IconLayer({
id: 'icon-layer',
data: points,
getPosition: d => d.coordinates,
getIcon: d => d.iconName,
getSize: 32,
iconAtlas: 'icons.png',
iconMapping: {
marker: { x: 0, y: 0, width: 64, height: 64, mask: true }
}
});
Атлас представляет собой единое изображение, содержащие множество иконок. Это снижает количество текстурных биндов и улучшает производительность GPU.
BitmapLayer используется для отображения больших
изображений, карт или подложек.
import { BitmapLayer } from '@deck.gl/layers';
const layer = new BitmapLayer({
id: 'bitmap-layer',
image: 'https://example.com/tiles/map.png',
bounds: [-74.1, 40.7, -73.9, 40.8]
});
В этом случае текстура привязывается к географическим координатам через bounding box. Deck.gl автоматически выполняет трансформацию в экранное пространство.
Загрузка изображений — дорогостоящая операция. Deck.gl и loaders.gl используют кэширование на нескольких уровнях:
Повторное использование одинаковых URL позволяет избежать повторной загрузки и повторного создания WebGL-ресурсов.
Mipmapping представляет собой набор уменьшенных копий текстуры, используемых при отрисовке объектов вдали.
gl.generateMipmap(gl.TEXTURE_2D);
Преимущества:
В Deck.gl mipmapping используется автоматически при соответствующих настройках слоёв и поддержке формата изображения.
Поддерживаемые форматы:
Декодирование может происходить:
ImageBitmap (оптимизировано)Использование ImageBitmap снижает нагрузку на главный
поток и ускоряет upload в GPU.
При большом количестве маркеров создание отдельной текстуры для каждой иконки приводит к деградации производительности. Решение — объединение в атлас.
Структура mapping:
{
car: { x: 0, y: 0, width: 64, height: 64, anchorY: 64 },
bus: { x: 64, y: 0, width: 64, height: 64, anchorY: 64 }
}
Каждая иконка описывается:
anchor)GPU использует UV-координаты для выборки нужного фрагмента.
Текстуры отображаются через нормализованные координаты:
При наложении на геометрию каждая вершина получает UV-атрибут, определяющий, какой участок текстуры используется.
Пример концепции:
Deck.gl генерирует эти данные автоматически для стандартных слоёв.
WebGL поддерживает режимы:
CLAMP_TO_EDGEREPEATMIRRORED_REPEATВ Deck.gl выбор режима зависит от типа слоя и характера изображения. Например:
CLAMP_TO_EDGEREPEATТекстуры в Deck.gl загружаются в рамках жизненного цикла слоя:
При обновлении данных возможно:
На практике встречаются следующие проблемы:
CORS блокировка
premultiplied alpha несоответствие
несовпадение размеров атласа
утечка GPU памяти
Основные стратегии:
ImageBitmapЭффективная работа с текстурами напрямую влияет на FPS при больших наборах геоданных и визуализаций.