# Per-vertex color gradient fill

**URL:** <https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679>\
**Category:** Coding Questions\
**Created:** [March 27, 2019, 12:26pm UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679 "2019-03-27T12:26:32Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![cdaein](https://avatars.discourse-cdn.com/v4/letter/c/8e7dd6/32.png) [@cdaein](https://discourse.processing.org/u/cdaein)\
**Post date:** [March 27, 2019, 12:26pm UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/1 "2019-03-27T12:26:32Z")

</div>

I’m trying to color each vertex of a rectangle differently to create a nice, smooth gradient fill inside. But when I run the sketch below, it looks like the shapes are broken into triangles and I see a clear band - is there any way I can make all gradients to connect smoother? Maybe I should look into GLSL shaders? Any pointers would be appreciated.

```java
void setup() {
  size(400, 400, P2D);
}

void draw() {
  noStroke();
  beginShape();
  fill(255, 0, 0);
  vertex(0, 0);
  fill(0, 255, 0);
  vertex(width, 0);
  fill(0, 0, 255);
  vertex(width, height);
  fill(255, 255, 0);
  vertex(0, height);
  endShape();
}

```

---

<div class="post-metadata">

**Author:** ![cansik](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/cansik/32/8815_2.png) [@cansik](https://discourse.processing.org/u/cansik)\
**Post date:** [March 27, 2019, 1:09pm UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/2 "2019-03-27T13:09:38Z")

</div>

I think the problem is that you defined the vertices in the _wrong_ order, which leads to a bad interpretation of the polygon. If I run your sketch I get this output image, which shows the clear green band:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/2/21e70268d4314a8bddd0571ee75be83c78fb06dd.png)

When you switch the second and last vertex (to counter-clockwise order), then it seems to be more equally distributed:

![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/7/758ea06dd57519fca4b89cc33e5cc36cab72a443.png)

The code for that would be like this:

```java
void setup() {
  size(400, 400, P2D);
}

void draw() {
  noStroke();
  beginShape();
  fill(255, 0, 0);
  vertex(0, 0);
  fill(0, 255, 0);
  vertex(0, height);
  fill(0, 0, 255);
  vertex(width, height);
  fill(255, 255, 0);
  vertex(width, 0);
  endShape();
}

```

---

<div class="post-metadata">

**Author:** ![cansik](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/cansik/32/8815_2.png) [@cansik](https://discourse.processing.org/u/cansik)\
**Post date:** [March 27, 2019, 1:11pm UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/3 "2019-03-27T13:11:30Z")

</div>

Even simpler solution: You could also leave your code as it is and tell processing which [polygon mode](https://processing.org/reference/beginShape_.html) for the shape it should use.

```java
beginShape(QUAD);

```

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/e/e3d9d858649c35560c38e128227ff7f3bcbf4db8.png)

---

<div class="post-metadata">

**Author:** ![cdaein](https://avatars.discourse-cdn.com/v4/letter/c/8e7dd6/32.png) [@cdaein](https://discourse.processing.org/u/cdaein)\
**Post date:** [March 27, 2019, 1:21pm UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/4 "2019-03-27T13:21:02Z")

</div>

Wow, I learned something new today! Thank you very much, @cansik !

---

<div class="post-metadata">

**Author:** ![cdaein](https://avatars.discourse-cdn.com/v4/letter/c/8e7dd6/32.png) [@cdaein](https://discourse.processing.org/u/cdaein)\
**Post date:** [March 27, 2019, 4:15pm UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/5 "2019-03-27T16:15:09Z")

</div>

I am trying @cansik 's suggestion and it works to some degree. It seems to depend on what colors are being used. Some colors bands are more pronounced:

```java
void setup() {
  size(400, 400, P2D);
  frameRate(4);
}

void draw() {
  noStroke();

  beginShape();
  fill(random(255), random(255), random(255));
  vertex(0, 0);
  fill(random(255), random(255), random(255));
  vertex(0, width);
  fill(random(255), random(255), random(255));
  vertex(width, height);
  fill(random(255), random(255), random(255));
  vertex(width, 0);
  endShape();
}

```

I am wondering whether there’s a way to interpolate between the two points on the diagonal.

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [March 28, 2019, 9:36pm UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/6 "2019-03-28T21:36:02Z")

</div>

> [@cdaein](#):
>
> I am wondering whether there’s a way to interpolate between the two points on the diagonal.

Well, perhaps create finer control by building a square out of more vertices? – you don’t have to use only 4. Intermediate points can be created dynamically with PVector.lerp. Intermediate colors can be created with lerpColor. The space and color ratios don’t need to be the same, of course…

---

<div class="post-metadata">

**Author:** ![cdaein](https://avatars.discourse-cdn.com/v4/letter/c/8e7dd6/32.png) [@cdaein](https://discourse.processing.org/u/cdaein)\
**Post date:** [March 28, 2019, 10:21pm UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/7 "2019-03-28T22:21:50Z")

</div>

thanks, @jeremydouglass  
I ditched the idea of using only 4 vertices, and instead implemented bilinear interpolation for all the pixels, and now it’s all looking good.

 ![17%20PM](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/5/5e93223a63db0583278d4844b51a99037e3627ec.png)

Below is my crude attempt at implementing the algorithm. If anyone has a better suggestion, I’d appreciate it.

```auto
/* 
 bilinear interpolation. needs colors for each corner
 0 | 2
 --+--
 1 | 3
 */
color[] interpolateBilinear(int w, int h, color[] corners) {
  color[] arr = new color[w * h];
  for (int x = 0; x < w; x++) {
    float xinc = (float) x/w;
    color t = lerpColor(corners[0], corners[2], xinc);
    color b = lerpColor(corners[1], corners[3], xinc);
    for (int y = 0; y < h; y++) {
      float yinc = (float) y/h;
      color m = lerpColor(t, b, yinc);
      arr[x + y*w] = m;
    }
  }
  return arr;
}

```

---

<div class="post-metadata">

**Author:** ![clankill3r](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/clankill3r/32/1098_2.png) [@clankill3r](https://discourse.processing.org/u/clankill3r)\
**Post date:** [July 29, 2019, 2:22pm UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/8 "2019-07-29T14:22:21Z")

</div>

Lerping every color is too slow for me. I needed gradients too, here is my solution (P2D / P3D):

```auto

void setup() {
  size(600, 600, P2D);
}

void draw() {
  background(0);
  
  gradient(color(255, 0, 0), color(0, 255, 0), NW);
  rect(10, 10, 100, 100);
  
  noGradient();
  rect(10, 10 + 100, 100, 100);

  gradient(color(255, 0, 0), color(0, 255, 0), color(0, 0, 255), color(255, 255, 0));
  rect(10 + 100, 10, 100, 100);
  
  
  
}

final static int N = UP;
final static int E = RIGHT;
final static int S = DOWN;
final static int W = LEFT;
final static int NE = 5;
final static int SE = 6;
final static int NW = 7;
final static int SW = 8;

boolean gradient = false;
int[] gradient_colors = new int[4]; // lt, rt, rb, lb

void gradient(int color_1, int color_2, int direction) {
  gradient = true;
  int LT = 0;
  int RT = 1;
  int RB = 2;
  int LB = 3;

  switch(direction) {
  case RIGHT: 
    {
      gradient_colors[LT] = color_1;
      gradient_colors[RT] = color_2;
      gradient_colors[RB] = color_2;
      gradient_colors[LB] = color_1;
      break;
    }
  case UP: 
    {
      gradient_colors[LT] = color_2;
      gradient_colors[RT] = color_2;
      gradient_colors[RB] = color_1;
      gradient_colors[LB] = color_1;
      break;
    }
  case LEFT: 
    {
      gradient_colors[LT] = color_2;
      gradient_colors[RT] = color_1;
      gradient_colors[RB] = color_1;
      gradient_colors[LB] = color_2;
      break;
    }
  case DOWN: 
    {
      gradient_colors[LT] = color_1;
      gradient_colors[RT] = color_1;
      gradient_colors[RB] = color_2;
      gradient_colors[LB] = color_2;
      break;
    }
  case NE: 
    {
      int color_lerp = lerpColor(color_1, color_2, 0.5f);
      gradient_colors[LT] = color_lerp;
      gradient_colors[RT] = color_2;
      gradient_colors[RB] = color_lerp;
      gradient_colors[LB] = color_1;
      break;
    }
    case SE: 
    {
      int color_lerp = lerpColor(color_1, color_2, 0.5f);
      gradient_colors[LT] = color_1;
      gradient_colors[RT] = color_lerp;
      gradient_colors[RB] = color_2;
      gradient_colors[LB] = color_lerp;
      break;
    }
    case SW: 
    {
      int color_lerp = lerpColor(color_1, color_2, 0.5f);
      gradient_colors[LT] = color_lerp;
      gradient_colors[RT] = color_1;
      gradient_colors[RB] = color_lerp;
      gradient_colors[LB] = color_2;
      break;
    }
    case NW: 
    {
      int color_lerp = lerpColor(color_1, color_2, 0.5f);
      gradient_colors[LT] = color_2;
      gradient_colors[RT] = color_lerp;
      gradient_colors[RB] = color_1;
      gradient_colors[LB] = color_lerp;
      break;
    }
    
  }
}

void gradient(int color_1, int color_2, int color_3, int color_4) {
  
  gradient = true;
  gradient_colors[0] = color_1;
  gradient_colors[1] = color_2;
  gradient_colors[2] = color_3;
  gradient_colors[3] = color_4;
}

void noGradient() {
  gradient = false;
}

void rect(float a, float b, float c, float d) {
  if (!gradient) {
    g.rect(a, b, c, d);
  } else {
    gradient_rect(a, b, c, d);
  }
}

void gradient_rect(float a, float b, float c, float d) {
  
  int bk_fill = g.fillColor;
  
  float hradius, vradius;
  switch (g.rectMode) {
  case CORNERS:
    break;
  case CORNER:
    c += a; 
    d += b;
    break;
  case RADIUS:
    hradius = c;
    vradius = d;
    c = a + hradius;
    d = b + vradius;
    a -= hradius;
    b -= vradius;
    break;
  case CENTER:
    hradius = c / 2.0f;
    vradius = d / 2.0f;
    c = a + hradius;
    d = b + vradius;
    a -= hradius;
    b -= vradius;
  }

  if (a > c) {
    float temp = a; 
    a = c; 
    c = temp;
  }

  if (b > d) {
    float temp = b; 
    b = d; 
    d = temp;
  }

  float x1 = a;
  float y1 = b;
  float x2 = c;
  float y2 = d;

  beginShape(QUADS);

  fill(gradient_colors[0]); 
  vertex(x1, y1);

  fill(gradient_colors[1]);
  vertex(x2, y1);

  fill(gradient_colors[2]);
  vertex(x2, y2);

  fill(gradient_colors[3]); 
  vertex(x1, y2);

  endShape();
  
  g.fillColor = bk_fill;
}

```

---

<div class="post-metadata">

**Author:** ![LuisFerreira](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/luisferreira/32/9493_2.png) [@LuisFerreira](https://discourse.processing.org/u/LuisFerreira)\
**Post date:** [June 3, 2020, 8:04am UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/9 "2020-06-03T08:04:47Z")

</div>

Hi, i came here to try to figure out a solution to re-paint a shape per vertex, without having to explicitly re-enter the vertexes. Don’t think this is possible according to what i have read so far.

I read these comments and i think you might be happy with this library i put together after reading a great tutorial about color gradients in Processing: [https://luisferreira.space/projects/BetterGradients/](https://luisferreira.space/projects/BetterGradients/)

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [June 3, 2020, 9:13am UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/10 "2020-06-03T09:13:18Z")

</div>

> [@LuisFerreira](#):
>
> … you might be happy with this library i put together…

> <https://github.com/LFBFerreira/BetterGradients/blob/1.0/src/luis/ferreira/libraries/color/Gradient.java#L15-L16>

As a general Java performance rule avoid [LinkedList](http://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/LinkedList.html) completely.

Even more so when accessing it by index, especially inside loops:

> <https://github.com/LFBFerreira/BetterGradients/blob/1.0/src/luis/ferreira/libraries/color/Gradient.java#L67-L69>

> <https://github.com/LFBFerreira/BetterGradients/blob/1.0/src/luis/ferreira/libraries/color/Gradient.java#L88-L92>

B/c on each index access, the whole [LinkedList](http://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/LinkedList.html) container needs to be traversed until the index is found:

> <https://stackoverflow.com/questions/322715/when-to-use-linkedlist-over-arraylist-in-java>

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [June 3, 2020, 1:34pm UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/11 "2020-06-03T13:34:05Z")

</div>

@LuisFerreira thanks for sharing this library. Great documentation as well. Have you submitted it for the PDE Contributions Manager yet?

Please consider posting this announcement to the forum Libraries and/or gallery.

---

<div class="post-metadata">

**Author:** ![LuisFerreira](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/luisferreira/32/9493_2.png) [@LuisFerreira](https://discourse.processing.org/u/LuisFerreira)\
**Post date:** [June 4, 2020, 10:31am UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/12 "2020-06-04T10:31:24Z")

</div>

> [@jeremydouglass](#):
>
> the PDE Contributions Manager yet?
> 
> Please consider posting this announcement to the forum Libraries and/or gallery.

I heard a similar comment just yesterday, after spending the last years using it. I will slowly refactor my projects to use ArrayList instead.

Thanks 🙂

---

<div class="post-metadata">

**Author:** ![LuisFerreira](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/luisferreira/32/9493_2.png) [@LuisFerreira](https://discourse.processing.org/u/LuisFerreira)\
**Post date:** [June 4, 2020, 10:36am UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/13 "2020-06-04T10:36:58Z")

</div>

Thank Jeremy. I haven’t made it official because i want to use the library a bit more, find out which interfaces are missing that could be handy, and be confident that it works without bugs. Same thing for a couple of other libraries i developed myself and i am using at the moment.

When i feel that these are stable and easy to use i will make an official release. In the meantime i am happy if people use them and report back any strange behaviour:

- [https://github.com/LFBFerreira/BetterGradients](https://github.com/LFBFerreira/BetterGradients)
- [https://github.com/LFBFerreira/MediaExport](https://github.com/LFBFerreira/MediaExport)
- [https://github.com/LFBFerreira/OscP5Manager](https://github.com/LFBFerreira/OscP5Manager)

As for the reason that brought me to this topic, i wanted to paint a shape per pixel, after the shape is defined or even loaded from an OBJ file. The function `setFill(color)` is probably know by most people, but i only found out about `setFill(index, color)` yesterday 😅 worked like a charm for my purpose

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [June 4, 2020, 3:28pm UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/14 "2020-06-04T15:28:39Z")

</div>

Thanks!

> [@LuisFerreira](#):
>
> only found out about `setFill(index, color)` yesterday 😅

I hadn’t seen this before. Is index a child shape index or a pixel index?

---

<div class="post-metadata">

**Author:** ![LuisFerreira](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/luisferreira/32/9493_2.png) [@LuisFerreira](https://discourse.processing.org/u/LuisFerreira)\
**Post date:** [June 5, 2020, 9:18am UTC](https://discourse.processing.org/t/per-vertex-color-gradient-fill/9679/15 "2020-06-05T09:18:44Z")

</div>

As far as i understand, its the index of the vertex. If you call getVertexCount() in a certain shape, you are able to use any index up to this count, anything above it will generate an error.

That’s actually how i found this method the first time, i wanted to set a fill with a color and alpha and i saw this method setFill(int, int), which i immediately assumed to be color+alpha. But it is index+color and now i finally found a proper use for it 🙂
