Quick answer: Compute derivative inputs unconditionally; branch only on the final value. Use fwidth(v) + smoothstep for AA edges. For texture sampling inside conditionals, use textureLod with explicit mip.
A signed-distance icon shader uses dFdx inside an if to anti-alias an edge. The AA bands or breaks because the derivative was wrong on the divergent side.
The Symptom
Visible banding at edges, especially near pixel-boundary thresholds. Smooth gradient shows discontinuities.
The Fix
// Bad — dFdx inside divergent branch
if (some_condition) {
float w = fwidth(uv.x);
color = smoothstep(0.5 - w, 0.5 + w, uv.x);
}
// Good — derivative computed unconditionally
float w = fwidth(uv.x);
float aa = smoothstep(0.5 - w, 0.5 + w, uv.x);
if (some_condition) {
color = vec4(aa);
}
Compute fwidth at the top of fragment, branch on the use later. Derivatives valid for every pixel.
Texture Mip in Branches
vec4 c = textureLod(tex, uv, 0.0); // explicit mip 0
if (cond) ALBEDO = c.rgb;
textureLod skips automatic mip selection (which depends on derivatives), making sampling safe inside conditionals.
Verifying
Render the edge close to the camera. AA should be smooth. With derivatives in branches: bands. Hoist; bands disappear.
“Derivative outside branches. Smoothstep on the result. Edges anti-alias.”
Related Issues
For shader uniform array, see uniform array. For shader uniform runtime, see runtime uniform.
Hoist derivatives. Smooth edges.