Intrinsics1 min read

fma

Computes a fused multiply-add.

Reading Time
1 min
Word Count
156
Sections
12
Try It Live

Test fma in a live shader

Open the playground, start from a visual preset, and wire fma into the fragment stage to see how it behaves with real values.

Open Playground

The fma function computes a * b + c as a fused multiply-add operation where supported. This can improve precision by avoiding an intermediate rounding step and can map directly to hardware multiply-add instructions.

Live Demo

Signature

bwsl
fma :: (T a, T b, T c) -> T {...}

Where T can be float, float2, float3, or float4.

Parameters

ParameterTypeDescription
aTMultiplicand
bTMultiplier
cTAddend

Return Value

Returns the result of a * b + c, computed componentwise for vector inputs.

Example

bwsl
pipeline ToneCurve {
fragment {
float3 color = sample(colorTex, input.uv).rgb;
// Apply contrast and brightness in one expression
float contrast = 1.15;
float3 pivot = float3(0.5, 0.5, 0.5);
float3 adjusted = fma(color - pivot, float3(contrast), pivot);
output.color = float4(saturate(adjusted), 1.0);
}
}

Common Use Cases

Linear Remapping

bwsl
// Map x from [0, 1] into [minValue, maxValue]
float mapped = fma(x, maxValue - minValue, minValue);

Polynomial Evaluation

bwsl
// Horner form for a cubic polynomial
float y = fma(a, x, b);
y = fma(y, x, c);
y = fma(y, x, d);

Transforming Colors

bwsl
// Per-channel scale and bias
float3 corrected = fma(color, scale, bias);

Accumulation

bwsl
// Accumulate weighted samples
sum = fma(sampleValue, weight, sum);

Precision

fma(a, b, c) is intended for fused multiply-add behavior. On a backend or target that cannot guarantee fusion, the compiler may lower it to equivalent multiply-plus-add operations.

Compiled Output

When compiled to GLSL:

glsl
fma(a, b, c)

When compiled to HLSL:

hlsl
mad(a, b, c)

When compiled to Metal:

metal
fma(a, b, c)

See Also

  • lerp - Linear interpolation
  • clamp - Clamp remapped values
  • saturate - Clamp to [0, 1]