Subtractive blending?
in
Programming Questions
•
1 month ago
I can do
additive blending. I'm using:
- PGraphics.blendMode(ADD);
- PGraphics.fill(0xff, 1);
This will slowly increase the from
black
to
white
. The image goes from (
0,0,0,0xff)
to (
1,1,1,0xff)
and eventually to (
0xff,0xff,0xff,0xff)
.
I have not been able to find a suitable way to slowly decrease the color from
white
to
black
. The SUBTRACT blend mode does not seem to work the way I'd expect. Any way I do it, it seems to clobber the alpha on the image, or go completely to black all at once. The method I have below is to filter(INVERT) the image, then draw white, then filter(INVERT) again. It works exactly as I'd like, but it's slow because the PGraphics has to be finalized twice.
Below I have a full and complete working example using this double invert method. I'd like to emulate this kind of result, but without all the inversion. I wonder if anyone has found a way to do this using a blendMode. Any help is appreciated.
- /**
- * Implement Additive and Subtractive blending
- * by John Colosi
- *
- * Unfortunately, subtractive blending is unintuitive.
- */
- // Buffers
- int screenX = 800;
- int screenY = 600;
- int imageX = 1600;
- int imageY = 1200;
- float ratioX = (float) imageX / screenX;
- float ratioY = (float) imageY / screenY;
- // Variables
- private PGraphics image;
- int red, green, blue;
- boolean isAdditive;
- void setup() {
- // Init screen buffer
- size(screenX, screenY, P2D);
- colorMode(RGB, 0xff);
- background(0, 0, 0, 0xff);
- // Init image buffer
- image = createGraphics(imageX, imageY, P2D);
- image.colorMode(RGB, 0xff);
- image.background(0, 0, 0, 0xff);
- // Init variables
- red = 0xff;
- green = 0xff;
- blue = 0xff;
- isAdditive = true;
- }
- void draw() {
- if (mousePressed) {
- if (isAdditive) drawBufferAdd();
- else drawBufferSubtract();
- image(image, 0, 0, screenX, screenY);
- }
- }
- void drawBufferAdd() {
- int x = (int) (mouseX * ratioX);
- int y = (int) (mouseY * ratioY);
- image.beginDraw();
- image.blendMode(ADD);
- image.rectMode(CENTER);
- image.noStroke();
- image.fill(red, green, blue, 1);
- image.rect(x, y, 256, 256);
- image.endDraw();
- }
- void drawBufferSubtract() {
- int x = (int) (mouseX * ratioX);
- int y = (int) (mouseY * ratioY);
- image.beginDraw();
- image.blendMode(ADD);
- image.filter(INVERT);
- image.rectMode(CENTER);
- image.noStroke();
- image.fill(red, green, blue, 1);
- image.rect(x, y, 256, 256);
- image.endDraw();
- image.beginDraw();
- image.filter(INVERT);
- image.endDraw();
- }
- public void keyPressed() {
- if (key == 's') image.save("GraphicsTest.png");
- if (key == 'r') red = red > 0 ? 0 : 0xff;
- if (key == 'g') green = green > 0 ? 0 : 0xff;
- if (key == 'b') blue = blue > 0 ? 0 : 0xff;
- if (key == 'z') isAdditive = !isAdditive;
- }
1