# Is there a better way to draw gradient colored ellipse?

**URL:** <https://discourse.processing.org/t/is-there-a-better-way-to-draw-gradient-colored-ellipse/22220>\
**Category:** Coding Questions\
**Created:** [June 28, 2020, 3:23pm UTC](https://discourse.processing.org/t/is-there-a-better-way-to-draw-gradient-colored-ellipse/22220 "2020-06-28T15:23:01Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nh3](https://avatars.discourse-cdn.com/v4/letter/n/d26b3c/32.png) [@nh3](https://discourse.processing.org/u/nh3)\
**Post date:** [June 28, 2020, 3:23pm UTC](https://discourse.processing.org/t/is-there-a-better-way-to-draw-gradient-colored-ellipse/22220/1 "2020-06-28T15:23:01Z")

</div>

I’m pretty new to Processing and graphical programming but keen to learn new stuff. I was trying to create a gradient colored sun for my project but I couldn’t find any obvious technique to do this. This is the solution I came up with:

```auto
void setup() {
  size(600,600);
  for (float k = 0; k < PI/2; k += PI/1000) { // looping through the highest point of the circle to the middle
    float xMul = cos(k);
    float yMul = sin(k);
    float x = xMul * height/4;
    float y = yMul * height/4;
    stroke(map(k,0,PI/2,255,255),map(k,0,PI/2,255,0),0); // defining the color gradient by the Y coordinate
    line(width/2-x,height/2-y,width/2+x,height/2-y); // drawing the top part of the circle
    line(width/2-x,height/2+y,width/2+x,height/2+y);
  }
}

```

It’s all in the setup method for simplicity. But anyways, I was wondering if there would be some more efficient way to do this. With my solution the program executes quite a many rows of code to accomplish such a simple task. Any ideas?

---

<div class="post-metadata">

**Author:** ![slow\_izzm](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/slow_izzm/32/5637_2.png) [@slow\_izzm](https://discourse.processing.org/u/slow_izzm)\
**Post date:** [June 28, 2020, 3:53pm UTC](https://discourse.processing.org/t/is-there-a-better-way-to-draw-gradient-colored-ellipse/22220/2 "2020-06-28T15:53:04Z")

</div>

That is one way to dray the circle, for a smoother color ramp you can use `lerpColor()`.  
[https://processing.org/reference/lerpColor\_.html](https://processing.org/reference/lerpColor_.html)

Here another of many ways to accomplish this …

```auto
void setup() {
  size(500, 500);
  noStroke();
  background(3, 7, 11);

  drawSunGradient(color(#F0BA70), color(#C12600), 450, 3);
}

void drawSunGradient(color fromColor, color toColor, final int diam, final int inc) {
  for (int x = diam; x > 0; x -= inc) {
    float inter = map(x, 0, diam, 0, 1.0);
    color lerpedColor = lerpColor(fromColor, toColor, inter);
    fill(lerpedColor);
    circle(width*0.5, height*0.5, x);
  }
}

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [June 29, 2020, 10:59am UTC](https://discourse.processing.org/t/is-there-a-better-way-to-draw-gradient-colored-ellipse/22220/3 "2020-06-29T10:59:08Z")

</div>

Hello,

> [@nh3](#):
>
> create a gradient colored sun for my project

Advanced topic…

This may be of interest:

> [@Adding an image to shape?](https://discourse.processing.org/t/adding-an-image-to-shape/21105):
>
> How do you add a background for a shape? ie instead of filling a circle with a colour, fill it with an image?

You can create an image with Processing, other tools or use an existing one (with permission if needed).

`:)`

---

<div class="post-metadata">

**Author:** ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)\
**Post date:** [June 29, 2020, 3:07pm UTC](https://discourse.processing.org/t/is-there-a-better-way-to-draw-gradient-colored-ellipse/22220/4 "2020-06-29T15:07:37Z")

</div>

Welcome to the forum! 🙂

> [@nh3](#):
>
> I was wondering if there would be some more efficient way to do this

There is a more efficient way, but efficient ways are not always easy. By programming the GPU you can create gradients, but it’s a different language called GLSL. If you’re starting with Processing then you can look at this in a year or two 🙂

The reason it’s faster it’s because there are no loops. The GPU calculates all the pixel colors in parallel. I’ll leave it here just in case someone needs faster gradients:

 ![2020-06-29-164634_800x800_scrot](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/a/a6845df61fcc20c6ebb0934761d709a3358784f6.jpeg)

```auto
PShader gradient;
void setup() {
  size(800, 800, P2D);

  gradient = new PShader(this, new String[] {
      "uniform mat4 transformMatrix;", 
      "attribute vec4 position;", 
      "attribute vec4 color;", 
      "varying vec4 va_color;", 
      "varying vec2 va_pos;",
      "void main() {", 
      " gl_Position = transformMatrix * position;", 
      " va_color = color;",
      " va_pos = position.xy;",
      "}"
    }, new String[] {
      "uniform vec2 center;",
      "uniform vec3 centerColor;",
      "uniform float radius;",
      "uniform bool linear;",
      "varying vec4 va_color;", 
      "varying vec2 va_pos;",
      "void main() {",
      " float d = (linear ? distance(center.y, va_pos.y) : distance(center, va_pos))/radius;",
      " vec3 c = mix(centerColor / 255.0, va_color.rgb, min(d*d, 1.0));",
      " gl_FragColor = vec4(c, va_color.a);", 
      "}"
    });
}

void draw() {
  float x = random(width);
  float y = random(height);
  float radius = random(20, 200);

  shader(gradient); // activate the shader. Next shapes are affected by it.
  gradient.set("center", x, y); // set the center of the gradient
  gradient.set("radius", radius); // set the radius of the gradient
  gradient.set("linear", false); // two modes: linear and radial
  gradient.set("centerColor", random(255), random(255), random(255)); // use 3 floats here!
  fill(random(255), random(255), random(255)); // the outer color
  noStroke();
  circle(x, y, radius * 2); // you can draw any shape, not just circles
  resetShader(); // deactivate the shader. Next shapes use default rendering
  // ...draw something else here
}

```

The “linear” mode I implemented is just a vertical gradient. You can change `.y` to `.x` to make it horizontal. To allow any angle it needs some work. Instead of `center` and `radius` we should define `startPos` and `endPos` for the shader.

Note that `center` and `radius` do not need to match the shape you draw. You can draw a radial gradient in a square. Or set the center of the gradient in the top-left corner of the window and the shape on the center. You can experiment 🙂

Another note: centerColor must be 3 floats. It won’t work if you use integers. Fortunately `random()` produces floats.

One place to learn about shaders is the [https://thebookofshaders.com/](https://thebookofshaders.com/) (oops, link was wrong! fixed)

ps. Forgot to mention that the gradient is exponential. You can replace `d*d` with `d` to distribute the colors uniformly instead. Or with `pow(d, 3.0)` for a more extreme exponential distribution.
