I'm using Shader-toy to experiment and try to learn a bit the shader science. As exercise I wan to replicate some of the wikipedia math plots. I've started with a Super Formula.

What I want to achieve is this:

enter image description here

(taken from this wikipedia image)

This image shows the parameter of the super formula thing:

  • a=b=1,
  • m=3,
  • n1=5,
  • n2=18 and
  • n3=18

I've looked for a similar example, simplified it and try to reproduce my curve.

In shader-toy this is my code:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
    // Variables to be fed into the formula
    float a = 1.0;
    float b = 1.0;
    float m = 3.;
    float n1 = 5.0;
    float n2 = 18.;
    float n3 = 18.;

    vec2 uv = fragCoord.xy / iResolution.xy;

    // translation
    vec2 sf = uv - 0.5;

    // r of the current point
    float pr = sqrt(sf.x*sf.x + sf.y*sf.y);
    // Angle (Phi) of the current point
    float f = atan(sf.y/sf.x);

    // The formula itself. Division by 10.0 added to scale the result down a bit.
    float r = pow((pow(abs(cos(f*m/4.0)/a),n2) + pow(abs(sin(f*m/4.0)/b), n3)), -(1.0/n1)) / 10.;

    // Output with coloring by relative radius
    fragColor = (pr <= r) ? 
        vec4(1., 0., 0., 1.0) : 
        vec4(0.1, 0.1, 0.1, 1.0);

But I'm achieving a different shape:

enter image description here

What am I doing wrong?


1 Answer 1


Instead of atan(sf.y/sf.x), use atan(sf.y,sf.x). This works because it takes the sign into consideration. Dividing the two numbers loses the sign bit data, so which quadrant you are in is unknown.

You can add fragColor=vec4(pr,f,0.0,1.0); to see what is going on.

Also, if you want to fix your aspect ratio (the image stretching) add sf.y *= iResolution.y/iResolution.x; after the declaring sf.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .