reckfellENGINE

Texture blit: texture-processing shaders

Inputs, target coordinates, four outputs and RGBA blend equations.

On this page

texture_blit defines one GPU operation on DrawableTexture2D. Its sole blit() function runs for destination-rectangle pixels. It is not a canvas_item effect automatically evaluated every time the texture is displayed.

Complete tinted copy shader

Create a ShaderMaterial containing this Shader and pass it as the final BlitRect argument. Initialize the destination using Setup first; a complete C# helper is in the DrawableTexture2D guide.

Shader
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) scales the entire source into the destination rect. Use the destination dimensions for a full-target write. Edit tint on the ShaderMaterial; the new uniform takes effect on the next blit.

Blend modes

S is shader output, D is the previous destination, and a is S.a. The checked ordinary RGBA8 path uses these equations before format clamping:

ModeRGBAlpha
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)

A custom shader without render_mode uses blend_disabled. The DrawableTexture2D default material explicitly uses blend_mix. Do not transfer one default to the other. Here add/sub RGB is not multiplied by alpha; the table does not promise identical CanvasItem or all-format arithmetic.

Shader premultiplied alpha is supported. Use this complete example for straight, not-yet-premultiplied RGBA. Remove the RGB multiplication when the input is already premultiplied.

Shader
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;
}

Use a ShaderMaterial for this mode. In this BlitMaterial version, the declared PremultipliedAlpha value exceeds the current cache range; that path is not executed by these checks and should not be invoked. The wrapper's other five modes and shader blend_premul_alpha are different paths.

Four inputs and four outputs

Declare sampler2D inputs with hint_blit_source0 through hint_blit_source3. Supplied sources are bound by order, not variable name. MODULATE contains the operation's color argument, but your code must apply it: COLOR0 is not automatically multiplied by it.

A complete two-source/four-output shader:

Shader
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);
}

Use DrawableOps.Split from the linked guide. It supplies first/second sources and three extra destinations. target_size must match the actual base destination dimensions for this diagnostic FRAGCOORD output; the default example uses 64×32.

COLOR0 maps to the primary destination; COLOR1 through COLOR3 map to extra destinations. Outputs without a bound destination are discarded. However, a bound output not assigned by user code receives opaque black (0,0,0,1) in current RD, not transparent color. Do not leave it unwritten expecting existing pixels to survive; blend_disabled overwrites them.

Coordinates and built-ins

UV spans 0 through 1 across the destination rectangle, allowing a full source sample. FRAGCOORD.xy is a pixel center in the current destination texture mipmap level, not the window or viewport. For a partial 32×16 rectangle in a 64×32 target, UV and FRAGCOORD/target size differ.

Type and nameMeaning
in float TIMERenderer time at the operation; it does not schedule another blit. Follows Engine.TimeScale, not tree pause. Rollover is rendering/limits/time/time_rollover_secs, normally 3600 seconds.
in float PI / TAU / EMathematical constants.
in vec4 FRAGCOORDDestination pixel center; xy in target-level pixels.
in vec2 UVNormalized destination-rectangle coordinates.
in vec4 MODULATEOperation color; a multiplier, not a channel write mask.
out vec4 COLOR0 / COLOR1 / COLOR2 / COLOR3Corresponding destination RGBA. Current RD initializes each to (0,0,0,1).

in is read-only and out is a result. This type has no CanvasItem vertex(), fragment(), TEXTURE or COLOR: declare sources and outputs according to the texture_blit contract. TIME and constants are global; remaining names belong to blit().

Constraints and troubleshooting

The 1–4 destinations must have equal dimensions and the selected mipmap level. Sources cannot alias destinations. Resource BlitRect does not support AtlasTexture as a crop: use the underlying atlas and compute UV yourself. Uniform/source/time changes without a new operation do not update stored pixels. Alternate two resources for an effect chain.

SymptomCheck
Material has no intended effectshader_type texture_blit and material passed to the current blit call.
Alpha is stored rather than blendedCustom shader render_mode; its default is blend_disabled.
Premultiplied result is too darkRGB may have been multiplied by alpha twice.
Extra destination turns blackExplicit assignment to its COLOR1/2/3.
Coordinates appear offsetRectangle UV versus destination FRAGCOORD, especially at a mipmap level.
An individual channel was not preservedMODULATE is not a channel mask; use an explicit formula and separate previous-value source.

Three complete shaders, the listed ordinary RGBA8 blend modes, outputs and coordinates are checked on Windows Forward+/Vulkan. Other color formats, the complete renderer/platform matrix and performance are not fully runtime-accepted here. The BlitMaterial cache limitation is source-identified and its unsafe enum is not invoked; engine core was not changed for this documentation.

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.