Per-vertex color gradient fill

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


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;
}

1 Like