Chrisstar
Chrisstar

Reputation: 646

4 point color interpolation in HCL space

I'm generating 4 point gradients (each corner). To do this I have a set color for each corner which is interpolated in HCL space. As this is quite hard to do yourself I am using a library (chroma.js) and it's integrated scale() function. Because there is no way to interpolate between more than two colors, the approach I am using is to first interpolate on the x axis and then on y. The problem with this approach is that there are artifacts in the middle when the path chosen for interpolation changes:

HCL interpolation

As you can see in this picture, this doesn't happen with RGB interpolation, but it doesn't look as nice (colors can get a bit dull):

rgb interpolation

My question is now, is there a better way to interpolate to remove this split in the middle?

This is the code I am using to generate this image (it's messy as this is just a proof of concept):

var colors = ["#EC0000","#4D0277","#E8F600","#00A2EE"];
function makeGradientAlt(pix, colors){
  var div = 32;
  var wid = pix.data.width / div;
  var hei = pix.data.height / div;

  var mode = "hcl";
  //var tscale = chroma.bezier([tl, tr]).scale().correctLightness();
  //var bscale = chroma.bezier([bl, br]).scale().correctLightness();
  var tscale = chroma.scale([colors[0], colors[1]]).mode(mode);//.correctLightness();
  var bscale = chroma.scale([colors[2], colors[3]]).mode(mode);//.correctLightness();


  for(let cx = 0; cx < wid; cx++){
    let fac = cx / wid;
    let scale = chroma.scale([tscale(fac), bscale(fac)]).mode(mode);
    for(let cy = 0; cy < hei; cy++){
      let col = scale(cy / hei).hex();
      pix.ctx.fillStyle = col;
      pix.ctx.fillRect(cx * div, cy * div, div, div);
      //pix.setPixel(cx, cy, col[0], col[1], col[2]);
    }
  }
  //pix.updateCanvas();
}

Upvotes: 2

Views: 617

Answers (1)

Late contribution. I believe you are not experiencing a blending artifact on the middle of the matrix at all. Merely you have a very uneven source interpolation on the bottom x axis color ramp between your yellow and blue points, very noticeable between the fifth and sixth steps, which is polluting your 4 points blend in all rows above. Notice the huge contrast between the fifth greenish step on the bottom and sixth bluish step. That distortion is merely being reflected on all the rows above it, because you are generating them with interpolations on Y axis between the colors above and below on the two source X axis ramps. The same artifact is not happening on the upper source ramp, but the one on the bottom is so pronounced it is enough to affect all other blends.

I believe this artifact on the lower ramp might be due to an inaccurate implementation of HCL color space conversion itself, since it should be correctly generated by your code.

Upvotes: 2

Related Questions