# How do I use screen-space derivatives to antialias a parametric shape in a pixel shader?

In Valve's Alpha Tested Magnification paper, it mentions using "per-pixel screen-space derivatives" for doing anti-aliasing. My understanding is that this is the `ddx` and `ddy` intrinsic functions in HLSL?

I'm trying to draw parametric shapes (for example a circle: x² + y² < 1) in a shader, and I don't know how to use this technique to correctly anti-alias the edge pixels of my shape. Can someone provide an example?

For completeness, here is an example of the kind of pixel shader I'm making:

``````float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float dist = input.TexCoord.x * input.TexCoord.x
+ input.TexCoord.y * input.TexCoord.y;
if(dist < 1)
return float4(0, 0, 0, 1);
else
return float4(1, 1, 1, 1);
}
``````
-

Taking your example, you have a step function of the distance, which produces a perfectly hard (aliased) edge. A simple way to antialias the circle would be to turn that into a soft threshold, like:

``````float distFromEdge = 1.0 - dist;  // positive when inside the circle
float thresholdWidth = 0.01;  // a constant you'd tune to get the right level of softness
float antialiasedCircle = saturate((distFromEdge / thresholdWidth) + 0.5);
return lerp(outsideColor, insideColor, antialiasedCircle);
``````

Here I used a clamped linear ramp for a soft threshold function, but you could also use `smoothstep` or something else. The `+ 0.5` is to center the ramp on the mathematical location of the edge. Anyway, the point is that this function smoothly changes from `outsideColor` to `insideColor` over some range of distances, so if you pick `thresholdWidth` appropriately you'll get an antialiased-looking edge.

But how should you choose `thresholdWidth`? If it's too small, you'll get aliasing again, and if it's too large the edge will be overly blurry. Moreover, it'll generally depend on camera position: if `dist` is measured in world-space or texture-space units, then a `thresholdWidth` that works for one camera position will be wrong for another.

Here's where the screen-space derivatives come in (yes, they're the `ddx` and `ddy` functions as you guessed). By calculating the length of the gradient of `dist` you can get an idea how rapidly it's changing in screen space and use that to estimate the `thresholdWidth`, like:

``````float derivX = ddx(distFromEdge);
float derivY = ddy(distFromEdge);
Good answer - the code works nicely. +1 and accepted. But could I trouble you to expand on your answer and explain why this works? I'm a bit confused about what `derivX` and `derivY` actually represent. – Andrew Russell Aug 20 '12 at 7:55
@AndrewRussell Are you familiar with derivatives, as in calculus? `derivX` and `derivY` are just (approximations of) the partial derivatives of whatever expression you pass into `ddx` and `ddy`, with respect to screen-space x and y. If you haven't studied calculus, that is a bigger topic than I can explain here. :) – Nathan Reed Aug 20 '12 at 16:28
@Runonthespot OpenGL has derivatives; they're just called something else: `dFdx`/`dFdy` instead of `ddx`/`ddy`. – Nathan Reed Sep 9 '13 at 16:08