Texture Sampling in Depth

Gather* returns the four texels around the sample point in the order (-,+), (+,+), (+,-), (-,-) — i.e.

18.1 The main methods

Texture2D<float4>      gTex     : register(t0);
Texture2DArray<float4> gArray   : register(t1);
TextureCube<float4>    gCube    : register(t2);
Texture3D<float>       gVolume  : register(t3);
Texture2D<float>       gShadow  : register(t4);
SamplerState           gLinear  : register(s0);
SamplerState           gPoint   : register(s1);
SamplerComparisonState gCmp     : register(s2);

float4 SamplingTour(float2 uv, float3 dir, float3 uvw, float depthRef, uint layer)
{
    float4 a = gTex.Sample(gLinear, uv);                       // auto mip (needs derivatives)
    float4 b = gTex.Sample(gLinear, uv, int2(1, 0));           // with immediate texel offset (-8..7)
    float4 c = gTex.SampleLevel(gLinear, uv, 2.0);             // explicit mip 2
    float4 d = gTex.SampleBias(gLinear, uv, -0.5);             // sharper
    float4 e = gTex.SampleGrad(gLinear, uv, ddx(uv), ddy(uv)); // explicit gradients
    float4 f = gArray.Sample(gLinear, float3(uv, layer));      // array slice in .z
    float4 g = gCube.Sample(gLinear, dir);                     // direction, need not be normalized
    float  h = gVolume.SampleLevel(gLinear, uvw, 0);
    float  s = gShadow.SampleCmpLevelZero(gCmp, uv, dept
…

18.2 Gather order

Gather* returns the four texels around the sample point in the order (-,+), (+,+), (+,-), (-,-) — i.e. x = bottom-left (u0,v1), y = bottom-right (u1,v1), z = top-right (u1,v0), w = top-left (u0,v0). Useful for custom filters (PCF, bilateral upsampling, depth min/max).

18.3 Filtering & mipmapping concepts

Mip selection uses screen-space derivatives of the UVs; in compute (pre-SM 6.6) or divergent code use SampleLevel/SampleGrad.

Anisotropic filtering (up to 16×) improves surfaces at grazing angles.

Texel centers are at (i + 0.5) / size. For pixel-exact post-processing with SV_Position, use Load(int3(pos.xy, 0)) or uv = pos.xy * invSize.

sRGB: use _SRGB formats for color textures so sampling returns linear values.

18.4 Useful texture tricks

// Triplanar mapping: texture without UVs
float3 Triplanar(Texture2D t, SamplerState s, float3 p, float3 n, float scale)
{
    float3 w = pow(abs(n), 4); w /= (w.x + w.y + w.z);
    float3 x = t.Sample(s, p.yz * scale).rgb;
    float3 y = t.Sample(s, p.xz * scale).rgb;
    float3 z = t.Sample(s, p.xy * scale).rgb;
    return x * w.x + y * w.y + z * w.z;
}

// Flipbook animation from an atlas of cols×rows frames
float2 FlipbookUV(float2 uv, float frame, float cols, float rows)
{
    float f = floor(fmod(frame, cols * rows));
    float2 cell = float2(fmod(f, cols), floor(f / cols));
    return (cell + uv) / float2(cols, rows);
}