gather
Gathers four texel values from a 2x2 footprint.
Test gather in a live shader
Open the playground, start from a visual preset, and wire gather into the fragment stage to see how it behaves with real values.
Open PlaygroundLive Demo Pending
The gather function retrieves a single component from four texels in a 2x2 footprint around the sampling location. This is useful for custom filtering operations.
Signature
gather :: (texture2D tex, sampler samp, float2 uv, int component) -> float4 {...}
Parameters
| Parameter | Type | Description |
|---|---|---|
tex | texture2D | The texture to sample |
samp | sampler | Sampler state |
uv | float2 | Texture coordinates |
component | int | Color component (0=R, 1=G, 2=B, 3=A) |
Return Value
Returns a float4 containing the specified component from four texels:
.x= bottom-left texel.y= bottom-right texel.z= top-right texel.w= top-left texel
Example
pipeline CustomFilter {
fragment {
// Gather red channel from 2x2 footprint
float4 reds = gather(tex, input.uv, 0);
// Custom bilinear interpolation
float2 f = fract(input.uv * textureSize);
float bottom = lerp(reds.x, reds.y, f.x);
float top = lerp(reds.w, reds.z, f.x);
float result = lerp(bottom, top, f.y);
output.color = float4(float3(result), 1.0);
}
}Common Use Cases
Custom Bilinear Filter
// Manual bilinear with custom weights
float4 texels = gather(tex, uv, 0);
float2 uvFraction = fract(uv * texSize);
float filtered = dot(texels, computeWeights(uvFraction));Edge Detection
// Sobel filter using gather
float4 samples = gather(grayTex, uv, 0);
float horizontal = samples.y + samples.z - samples.x - samples.w;
float vertical = samples.z + samples.w - samples.x - samples.y;
float edge = sqrt(horizontal * horizontal + vertical * vertical);Shadow Map Filtering
// Gather depth values for custom PCF
float4 depths = gather(shadowMap, shadowUV, 0);
float4 comparisons = step(fragmentDepth, depths);
float shadow = dot(comparisons, float4(0.25));Height-Based Operations
// Gather heights for normal calculation
float4 heights = gather(heightMap, uv, 0);
float dx = (heights.y + heights.z) - (heights.x + heights.w);
float dy = (heights.z + heights.w) - (heights.x + heights.y);Depth of Field
// Gather for circle of confusion
float4 colors = gather(sceneTex, uv, component);
float4 cocs = gather(cocTex, uv, 0);
// Weighted blend based on CoCPerformance
gather is often more efficient than four separate texture samples when you need values from a 2x2 block, as it uses a single texture fetch.
Texel Order
The returned components follow a counterclockwise order starting from bottom-left: (bottom-left, bottom-right, top-right, top-left).
Compiled Output
When compiled to GLSL:
textureGather(tex, uv, component)
When compiled to HLSL:
tex.GatherRed(sampler, uv) // or GatherGreen, GatherBlue, GatherAlpha
When compiled to Metal:
tex.gather(sampler, uv, component)