Hi! What would be the right way to have multiple PGraphics with transparency and draw them on top of each other to avoid tinting?
I’ll try to show the issue with some images and code:
PGraphics pg;
int mode = 0;
void setup() {
size(600, 600, P2D);
}
void draw() {
}
void keyPressed() {
if (key == ' ') {
// draw random stuff on the background
randomSeed(0);
background(255, 40, 20);
for (int i=0; i<50; i++) {
pushMatrix();
translate(random(width), random(height));
rotate(i);
rectMode(CENTER);
noStroke();
fill(random(50), random(100), random(255));
rect(0, 0, 200, 50, 10);
popMatrix();
}
// capture the background image for mode 2
PImage bg = get();
// create the top layer
pg = createGraphics(width, height, P2D);
pg.beginDraw();
// The core of the issue: how to clear the layer?
if(mode == 0) {
pg.clear();
} else if(mode == 1) {
pg.background(255, 40, 20, 0);
} else {
pg.background(bg);
}
// draw white transparent lines
pg.strokeWeight(5);
pg.stroke(255, 40);
for (int i=0; i<200; i++) {
pg.line(i*3, 0, width-i*3, height);
}
pg.endDraw();
// draw the layer to the main canvas
image(pg, 0, 0);
save("mode" + mode + ".png");
mode = ++mode % 3;
}
}
In that program I create some random graphics as a background and a layer with transparency to place on top. In the real program there are many such layers.
If one uses clear()
to clear the PGraphics, I believe it’s setting every pixel to the color (0, 0, 0, 0) which is transparent black. If we draw transparent objects on such a layer, the transparent areas are tinted gray, as you can see the darkening of the red background, even if I’m drawing transparent white lines.
A second option would be to avoid clear()
and use background()
instead. In the second image you can see the result of calling backrgound with the red background color and 0 as alpha value. It no longer tints gray, but now everything is tinted red instead.
I assume the way to avoid any tint would be closer to the third approach: use the existing background image to clear the PGraphics, while setting the alpha to 0 (I didn’t do that in this program). I assume the way to do that would be to iterate over all pixels in the PGraphics and set the alpha value to 0. I don’t think any of the Processing functions allows to set just one channel (for instance, the alpha channel to 0). By doing this the transparent objects are not tinted to gray or red, but are only a combination of the drawing color and the background.
Can you suggest any references for learning about transparency and blending?
Is there a different technique you would use in this situation? (a blendMode, a shader…)