【发布时间】:2022-01-25 18:07:49
【问题描述】:
我正在做一些 blendMode(BURN) 来绘制一些形状。以及其他形状我需要直接用之前形状的结果颜色绘制,所以我需要自己生成混合结果颜色。
我正在寻找类似的东西:
let blendedColor = blendColorsBurn(color1, color2);
【问题讨论】:
标签: p5.js color-blending
我正在做一些 blendMode(BURN) 来绘制一些形状。以及其他形状我需要直接用之前形状的结果颜色绘制,所以我需要自己生成混合结果颜色。
我正在寻找类似的东西:
let blendedColor = blendColorsBurn(color1, color2);
【问题讨论】:
标签: p5.js color-blending
没有用于此的内置函数。在 2d 模式下,p5.js 利用画布的 globalCompositeOperation property,当设置为 color-burn 时,执行以下颜色混合操作:
将反转的底层除以顶层,然后将结果反转。
这听起来很简单,但我想验证它的含义,因此我决定尝试快速测试实现。按 shift 和 control 键分别查看内置的 BURN blendMode 和我的计算。
let existingContent;
let newContent;
let manualBurn;
let scaleFactor = 1;
function preload() {
existingContent = loadImage("https://www.paulwheeler.us/files/existing-content.png");
newContent = loadImage("https://www.paulwheeler.us/files/new-content.png");
}
function setup() {
createCanvas(windowWidth, windowHeight);
noLoop();
scaleFactor = height / newContent.height;
manualBurn = createImage(newContent.width, newContent.height);
// Divides the inverted bottom layer by the top layer, and then inverts the result.
for (let x = 0; x < newContent.width; x++) {
for (let y = 0; y < newContent.height; y++) {
const c1 = existingContent.get(x, y);
const c2 = newContent.get(x, y);
if (alpha(c2) > 0) {
let a = alpha(c1) / 255;
// Inverted bottom layer
let [inv_r, inv_g, inv_b, inv_a] = [
// Subtracting from alpha instead of 1 is to deal with pre-multiplied alpha
a - red(c1) / 255,
a - green(c1) / 255,
a - blue(c1) / 255,
1 - alpha(c1) / 255,
];
// divided by the top layer
let [div_r, div_g, div_b, div_a] = [
inv_r / (red(c2) / 255),
inv_g / (green(c2) / 255),
inv_b / (blue(c2) / 255),
inv_a / (alpha(c2) / 255),
];
// inverted
let out = [255 * (1 - div_r), 255 * (1 - div_g), 255 * (1 - div_b), max(alpha(c2), 255 * (1 - div_a))];
manualBurn.set(x, y, out);
} else {
manualBurn.set(x, y, c1);
}
}
}
manualBurn.updatePixels();
}
function keyPressed() {
redraw();
}
function keyReleased() {
redraw();
}
function draw() {
clear();
scale(scaleFactor);
if (keyIsDown(CONTROL)) {
blendMode(BLEND);
image(manualBurn, 0, 0);
} else {
image(
existingContent,
0,
0
);
if (keyIsDown(SHIFT)) {
blendMode(BURN);
image(newContent, 0, 0);
}
}
}
html, body {
margin: 0;
padding: 0;
}
body {
background-image: url("https://www.paulwheeler.us/files/checkerboard.jpeg");
background-repeat: repeat;
background-size: 200px;
}
canvas {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
肯定有一些问题:
colorMode(RGB, 1, 1, 1, 1) 不起作用,因为 red()、green() 和 blue() 函数四舍五入为整数?♂️【讨论】: