# Drawing an Ellipse via its implicit equation in a PIxel Shader

This topic is 3650 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

In this thread we were discussing the possibility of drawing an ellipse in a pixel shader through its implicit equation. I went ahead and tried it but it is not as easy as it seems. In this particular case, I'm trying to generate the outline of an ellipse, so I have two parameters: an outline "width" and a "fade to black" distance, which generates a gradient from the outline color and the transparent background (for no particular reason, I just wanted to smooth the edges). This is the image generated by the pixel shader: As you may have noticed, the width of the outline is wider at the points where its curve changes orientation (ie at the full extents of its semimajor axis in this case) and thinner at its semiminor axis. This is due to the code that I'm using to generate it, I guess. Here follows the pixel shader code:
float a; // Semimajor Axis
float b; // Semiminor Axis

float fOutlineWidth = 0.05;

float4 circleColor = float4(1,0,0,0);
float4 cBlack = float4(0,0,0,0);

float h = 0; // Center X coordinate
float k = 0; // Center Y coordinate

float4 ps_main( float2 texCoord  : TEXCOORD0 ) : COLOR
{

float x = texCoord.x;
float y = texCoord.y;

float fEllipse = pow(x-h,2) / (a*a) + pow(y-k,2) / (b*b);
float fDistance = abs(1-fEllipse);

float4 color;

if (fDistance <= fOutlineWidth)
color = circleColor;
else if (fDistance <= fOutlineWidth + fFadeWidth)
else
color = cBlack;

return color;
}


It's very simple. Just compute the ellipse's implicit equation. When it's very close to 1, if it's under a certain value (fOutlineWidth or fOutlineWidth < x < fOutlineWidth + fFadeWidth) apply a certain color. But it provokes the above effect, which is due to these distances not being as "linear" as say, in the case of a circle. So what should I do in order to make it render a "perfect" ellipse? Maybe using two ellipses? With the semimajor/minor axis slightly larger and compute the distance between these two ellipses, and use that value to see which color to apply? Or is there a more elegant way? Thanks in advance!

##### Share on other sites
this is the best I could do tonight, I will see if i can refine it later if I feel like it.
Time1 advances 0.005f per frame in the program

   float a = (sin(Time1)+1)/6+0.05; // Semimajor Axis   float b = (cos(Time1)+1)/6+0.05; // Semiminor Axis   float h = 0.5; // Center X coordinate   float k = 0.5; // Center Y coordinate	   float x = texCoord.x;   float y = texCoord.y;   float theta = acos((x-h)/a);   if (y < k)     theta = Pi - theta + Pi;   float x2 = h + a * cos(theta);   float y2 = k + b * sin(theta);   float fEllipse = pow(x-h,2) / (a*a) + pow(y-k,2) / (b*b);   float fDistance = abs(1-fEllipse);   float fDistance2 = sqrt((x2 - x)*(x2 - x) + (y2-y)*(y2-y));         float4 color;    if (fDistance2 <= fOutlineWidth/10)      color.x = circleColor.x;    else if (fDistance <= fOutlineWidth)      color.y = circleColor2.y;    else      color = cBlack;    return color;

the green color is your original function, the red addition is my new function, both of them overlapping make a fairly decent ellipse, but the smoothing function as you wrote it doesn't work on my addition because the coordinates go screwy on the left and right extremes of the ellipse.

program and fx file

anyway hope this helps

##### Share on other sites
Can you maybe for a given pixel position, compute a vector that is perpendicular to the closest point on the ellipse, and then project the pixel position onto that vector, telling you how far off the curve you are, to give a uniform width around the whole ellipse?

1. 1
2. 2
frob
16
3. 3
4. 4
5. 5

• 15
• 13
• 14
• 75
• 22
• ### Forum Statistics

• Total Topics
632145
• Total Posts
3004345

×