reckfellENGINE

Texture blit: шейдеры обработки текстур

Источники, координаты цели, четыре выхода и формулы смешивания RGBA.

На этой странице

texture_blit задаёт одну GPU-операцию над DrawableTexture2D. Единственная функция blit() выполняется для пикселей прямоугольника назначения. Это не canvas_item-эффект, который автоматически выполняется при каждом отображении текстуры.

Полный шейдер копирования с окраской

Создайте ShaderMaterial с этим Shader и передайте его последним аргументом BlitRect. Перед записью инициализируйте цель через Setup; полный C#-помощник есть в руководстве DrawableTexture2D.

Шейдер
shader_type texture_blit;
uniform sampler2D source : hint_blit_source0;
uniform vec4 tint : source_color = vec4(1.0);
void blit() {
    COLOR0 = texture(source, UV) * MODULATE * tint;
}

Вызов target.BlitRect(rect, source, Colors.White, 0, material) берёт всю source и масштабирует в rect цели. Для всего результата используйте rect с размером цели. Uniform tint меняется на ShaderMaterial, но новое значение начнёт действовать только при следующем blit.

Режимы смешивания

S — выход шейдера, D — прежнее значение назначения, a — S.a. Для проверенного обычного RGBA8-пути действуют следующие правила до ограничения форматом:

РежимRGBAlpha
blend_disabledS.rgbS.a
blend_mixS.rgb × a + D.rgb × (1−a)a + D.a × (1−a)
blend_addS.rgb + D.rgbS.a + D.a
blend_subD.rgb − S.rgbD.a − S.a
blend_mulS.rgb × D.rgbS.a × D.a
blend_premul_alphaS.rgb + D.rgb × (1−a)a + D.a × (1−a)

Собственный шейдер без render_mode использует blend_disabled. Материал по умолчанию у DrawableTexture2D явно задаёт blend_mix. Не переносите предположение о режиме одного в другой. В add/sub RGB здесь не умножается на alpha; таблица не обещает такую же арифметику CanvasItem или всех цветовых форматов.

Premultiplied alpha поддерживается шейдером. Для прямого, ещё не умноженного RGBA используйте полный пример ниже. Если вход уже premultiplied, второе умножение RGB нужно убрать.

Шейдер
shader_type texture_blit;
render_mode blend_premul_alpha;
uniform sampler2D source : hint_blit_source0;
void blit() {
    COLOR0 = texture(source, UV) * MODULATE;
    COLOR0.rgb *= COLOR0.a;
}

Для этого режима используйте ShaderMaterial. У BlitMaterial данной версии объявленное PremultipliedAlpha выходит за пределы текущего кэша; этот путь не проверяется исполнением и не рекомендуется к вызову. Остальные пять режимов оболочки и сам shader blend_premul_alpha — разные пути.

Четыре источника и четыре выхода

Источник задаётся sampler2D с hint_blit_source0…hint_blit_source3. Переданные источники выбираются по порядку, не по имени переменной. MODULATE содержит цвет аргумента операции, но применить его должен код: COLOR0 не умножается на него автоматически.

Полный пример с двумя источниками и четырьмя выходами:

Шейдер
shader_type texture_blit;
uniform sampler2D source0 : hint_blit_source0;
uniform sampler2D source1 : hint_blit_source1;
uniform vec2 target_size = vec2(64.0, 32.0);
void blit() {
    COLOR0 = texture(source0, UV) * MODULATE;
    COLOR1 = texture(source1, UV) * MODULATE;
    COLOR2 = vec4(UV, 0.0, 1.0);
    COLOR3 = vec4(FRAGCOORD.xy / target_size, 0.0, 1.0);
}

Используйте DrawableOps.Split из связанного руководства. Он передаёт источники first/second и три дополнительные цели. target_size должен совпадать с реальным базовым размером цели для этой диагностической записи FRAGCOORD. Пример по умолчанию рассчитан на 64×32.

COLOR0 соответствует основной цели, COLOR1…3 — дополнительным. Неиспользуемые выходы без назначенной цели отбрасываются. Но назначенный выход, которому код не присвоил значение, в текущем RD получает непрозрачный чёрный (0,0,0,1), а не прозрачный цвет. Не оставляйте такой выход в надежде сохранить прежние пиксели; при blend_disabled он их перезапишет.

Координаты и встроенные значения

UV проходит от 0 до 1 по записываемому прямоугольнику и позволяет выбрать весь источник. FRAGCOORD.xy — центр пикселя целевой текстуры текущего mipmap-уровня, а не окна или viewport. У частичного rect размером 32×16 в цели 64×32 UV и FRAGCOORD/размер цели различаются.

Тип и имяЗначение
in float TIMEВремя рендерера в момент операции; не запускает повторный blit. Учитывает Engine.TimeScale, пауза дерева его не останавливает. Сброс rendering/limits/time/time_rollover_secs, обычно 3600 секунд.
in float PI / TAU / EМатематические константы.
in vec4 FRAGCOORDЦентр пикселя назначения; xy в пикселях целевого уровня.
in vec2 UVНормализованные координаты записываемого прямоугольника.
in vec4 MODULATEПереданный операции цвет; это множитель, не маска записи каналов.
out vec4 COLOR0 / COLOR1 / COLOR2 / COLOR3RGBA соответствующей цели. В текущем RD начальное значение каждого — (0,0,0,1).

in — чтение, out — результат. У этого типа нет vertex(), fragment(), TEXTURE или COLOR из CanvasItem: источники и выходы объявляются по контракту texture_blit. TIME и константы доступны глобально, остальные имена — в blit().

Ограничения и диагностика

1–4 цели должны быть одного размера; запрошенный mipmap обязан существовать. Источники не могут совпадать с целями. AtlasTexture не поддерживается ресурсным BlitRect как вырезка; берите исходный атлас и считайте UV самостоятельно. Изменение uniform, источника или времени без новой операции не обновляет записанные пиксели. Для цепочки эффектов используйте чередование двух ресурсов.

СимптомЧто проверить
Материал не даёт нужного эффектаshader_type texture_blit и передача material именно в текущий вызов blit.
Alpha записалась вместо смешиванияrender_mode собственного шейдера; по умолчанию blend_disabled.
Цвет слишком тёмный с premultiplied alphaRGB мог быть умножен на alpha дважды.
Дополнительная цель стала чёрнойЯвную запись нужного COLOR1/2/3.
Координаты смещеныРазличие UV прямоугольника и FRAGCOORD цели, особенно на mipmap.
Отдельный канал не сохранилсяMODULATE не является маской каналов; нужна явная формула и отдельный источник прежнего значения.

Проверены три полных шейдера, все приведённые режимы смешивания в обычном RGBA8, выходы и координаты на Windows Forward+/Vulkan. Настройки цветов других форматов, вся матрица рендереров/платформ и производительность не имеют здесь полной runtime-проверки. Ограничение кэша BlitMaterial выявлено по исходникам, опасный enum не запускается; ядро движка для этой документации не менялось.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.