Fill Ellipse from a fragment shader

I always rewriting some old 2D stuffs using old OpenGL glBegin/glEnd for use modern openGL statements.

I’m writing a fillOval implementation using a fragment shader instead of pushing a lot of vertices for drawing my ellipse.

The idea is to paint a classic rectangle (2 triangles composition) and use a fragment shader that discard all fragment that is not inside the ellipse.

As is, i push on OpenGL in order to draw my ellipse :

  • 4 vertices
  • 6 indices
  • 2 “vec2” uniforms
    • the center of the ellipse
    • the radius of the ellipse

my fragment shader (responsible to discard fragments) looks like this one:

#version 330

uniform vec2 u_centerOval;
uniform vec2 u_radiusOval;

layout(origin_upper_left) in vec4 gl_FragCoord;

out vec4 outputColor;

void checkFragment() {
   /**
    * Ellipse equation =  (x/a)2 + (y/b)2 = 1 
    *     a = horizontal radius
    *     b = vertical   radius 
    */
    
    float e1 =  ( gl_FragCoord.x - u_centerOval.x ) / ( u_radiusOval.x );
    float e2 =  ( gl_FragCoord.y - u_centerOval.y ) / ( u_radiusOval.y );
    
    float d  = (e1 * e1) + (e2 * e2);
    if( d > 1 ) {
       outputColor = vec4(1.0 , 0.0 , 0.0 , 1.0 ); // discard;
    }    
}

So, it works not so bad. I have an “aliasing” issue, but i will see this later.

But now, if i paint with this statement:


  g2d.setColor( Color.YELLOW );
  g2d.fillOval( 400 ,  50 ,  200 ,  100 );

i obtain this

But if i apply an affine transformation like this:


 g2d.transform( AffineTransform.identity().rotate( 0.2f , 400 + 100 , 50 + 50 ) );
 g2d.setColor( Color.YELLOW );
 g2d.fillOval( 400 ,  50 ,  200 ,  100 );
g2d.setTransform( null );

i obtain this

That’s quite normal since my fragment shader don’t take in account my affine transform.
It’s only my vertex shader that use it (and it rotate the rectangle as well).

i should inverse my transformation on gl_FragCoord in order to compute the ellipse equation ?
It’s a pain, all matrices are not invertible. I can pass it as an uniform.

Have you a better idea ?
At this point, maybe this technical approach is completely crazy but at first thinking i found it quite fun.

Best regards,
Sébastien.