Intrinsic Functions

The complete list is in Appendix 45.3.

The complete list is in Appendix 45.3. The most important groups:

12.1 Math

abs, sign, min, max, clamp(x, lo, hi) clamp to [0, 1] — often free on GPUs floor, ceil, round, trunc, frac rounding; frac(x) = x - floor(x) remainder with sign of x lerp(a, b, t) a + t * (b - a) step(edge, x)

x >= edge ? 1: 0 (note argument order) smoothstep(e0, e1, x) sqrt, rsqrt, rcp square root, reciprocal square root, reciprocal pow, exp, exp2, log, log2, log10

sin, cos, tan, asin, acos, atan, atan2(y, x), sincos(x, s, c), sinh, cosh, tanh radians, degrees mad(a, b, c) fma(a, b, c) fused multiply-add (double) isnan, isinf, isfinite modf(x, ip), frexp, ldexp

12.2 Geometric & matrix

dot, cross, length, distance, normalize, reflect(i, n), refract(i, n, eta), faceforward(n, i, ng), mul, transpose, determinant, lit(n_dot_l, n_dot_h, m) (legacy).

12.3 Bit & conversion

countbits, firstbithigh, firstbitlow, reversebits, asfloat, asint, asuint, asdouble, asuint(double, lo, hi), f16tof32, f32tof16, SM 6.6 pack_u8, pack_s8, unpack_u8u32, pack_clamp_u8, SM 6.4 dot4add_u8packed, dot4add_i8packed, dot2add.

12.4 Texture methods (objects, see Chapter 18)

t.Sample(s, uv [, offset]) filtered sample with automatic mip selection (PS, or CS/MS/AS with SM 6.6 compute derivatives) t.SampleLevel(s, uv, lod) explicit mip level — usable in any stage t.SampleBias(s, uv, bias) t.SampleGrad(s, uv, ddx, ddy)

t.SampleCmp(sc, uv, ref) / SampleCmpLevelZero depth comparison (shadow maps) t.Load(int3(x, y, mip)) unfiltered texel fetch t[uint2(x, y)] operator[] texel access (mip 0)

t.Gather(s, uv), GatherRed/Green/Blue/Alpha, GatherCmp fetch 4 texels of one channel size, mip count, array size t.CalculateLevelOfDetail(s, uv) LOD that Sample would use

12.5 Derivatives (pixel shaders; compute with SM 6.6)

ddx(v), ddy(v) (coarse or fine — implementation choice), ddx_coarse, ddy_coarse, ddx_fine, ddy_fine, fwidth(v) = abs(ddx(v)) + abs(ddy(v)).

// Anti-aliased grid lines using derivatives
float Grid(float2 uv, float lines)
{
    float2 g = abs(frac(uv * lines - 0.5) - 0.5) / fwidth(uv * lines);
    return 1.0 - saturate(min(g.x, g.y));
}

12.6 Synchronization & atomics (compute, Chapter 27–28)

GroupMemoryBarrierWithGroupSync, GroupMemoryBarrier, DeviceMemoryBarrier[WithGroupSync], AllMemoryBarrier[WithGroupSync], InterlockedAdd/Min/Max/And/Or/Xor/Exchange/CompareExchange/CompareStore.

12.7 Pixel-shader specials

clip(x), discard, printf (only when targeting SPIR-V, via Vulkan debug printf; not available in DXIL), IsHelperLane() (SM 6.6), EvaluateAttribute*, GetRenderTargetSampleCount(), GetRenderTargetSamplePosition(i).

🧪 Part I Exercises

Install DXC and compile the triangle shaders to DXIL and to SPIR-V; open both disassemblies (-Fc) and identify the input/output signatures.

Paste the same shader into Shader Playground or Compiler Explorer and compare DXC output at -Od and -O3.

Build the D3D11 host from §5.2; change the vertex colors and the clear color, then enable the debug layer and fix any warnings.

Draw a fullscreen triangle using only SV_VertexID and output the UV coordinates as color; explain why the image is red at the top-right and green at the bottom-left.

Write a pixel shader that draws a checkerboard using frac, floor, and fmod, then anti-alias its edges with fwidth.

Given a float4 v = float4(1,2,3,4), predict the results of v.wzyx, v.xxyy * 2, dot(v.xy, v.zw), and cross(v.xyz, v.yzx); verify by outputting them as colors.

Create a float4x4 translation matrix in HLSL and show that mul(v, M) and mul(M, v) give different results; then fix it with transpose.

Write the same branch with [branch] and [flatten] and compare the generated DXIL/DXBC.

Write overloaded Remap() functions for float, float2, and float3, plus a function using out and inout parameters.

Make a table of every semantic used in your shaders, which stage writes it, and which stage reads it; add nointerpolation to an integer material ID and verify it compiles.