HCL 中的 4 点颜色插值 space
4 point color interpolation in HCL space
我正在生成 4 点渐变(每个角)。为此,我为每个角设置了颜色,并在 HCL space 中进行了插值。因为这很难自己完成,所以我使用了一个库 (chroma.js),它集成了 scale() 函数。因为没有办法在两种以上的颜色之间进行插值,所以我使用的方法是先在 x 轴上插值,然后在 y 轴上插值。这种方法的问题是,当为插值选择的路径发生变化时,中间会出现伪影:
正如您在这张图片中看到的,RGB 插值不会发生这种情况,但它看起来不太好(颜色可能会有点暗淡):
我现在的问题是,是否有更好的插值方法来消除中间的分裂?
这是我用来生成这张图片的代码(这很乱,因为这只是一个概念证明):
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();
}
迟到的贡献。我相信您根本不会在矩阵中间遇到混合伪像。只是在黄色点和蓝色点之间的底部 x 轴色带上有一个非常不均匀的源插值,在第五步和第六步之间非常明显,这会污染上面所有行中的 4 点混合。请注意底部第五个绿色台阶和第六个蓝色台阶之间的巨大对比。这种失真仅反映在其上方的所有行上,因为您是通过在两个源 X 轴渐变上上方和下方的颜色之间的 Y 轴插值来生成它们的。同样的伪影没有出现在上部源斜坡上,但底部的伪影非常明显,足以影响所有其他混合。
我认为下斜坡上的这个伪影可能是由于 HCL 颜色 space 转换本身的实施不准确,因为它应该由您的代码正确生成。
我正在生成 4 点渐变(每个角)。为此,我为每个角设置了颜色,并在 HCL space 中进行了插值。因为这很难自己完成,所以我使用了一个库 (chroma.js),它集成了 scale() 函数。因为没有办法在两种以上的颜色之间进行插值,所以我使用的方法是先在 x 轴上插值,然后在 y 轴上插值。这种方法的问题是,当为插值选择的路径发生变化时,中间会出现伪影:
正如您在这张图片中看到的,RGB 插值不会发生这种情况,但它看起来不太好(颜色可能会有点暗淡):
我现在的问题是,是否有更好的插值方法来消除中间的分裂?
这是我用来生成这张图片的代码(这很乱,因为这只是一个概念证明):
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();
}
迟到的贡献。我相信您根本不会在矩阵中间遇到混合伪像。只是在黄色点和蓝色点之间的底部 x 轴色带上有一个非常不均匀的源插值,在第五步和第六步之间非常明显,这会污染上面所有行中的 4 点混合。请注意底部第五个绿色台阶和第六个蓝色台阶之间的巨大对比。这种失真仅反映在其上方的所有行上,因为您是通过在两个源 X 轴渐变上上方和下方的颜色之间的 Y 轴插值来生成它们的。同样的伪影没有出现在上部源斜坡上,但底部的伪影非常明显,足以影响所有其他混合。
我认为下斜坡上的这个伪影可能是由于 HCL 颜色 space 转换本身的实施不准确,因为它应该由您的代码正确生成。