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.