The same thing with 'transparent black'
How black or white the repainted section becomes is a function of the transparency of the fill color.
If you do the the same with transparent red, blue, green, the repeated painting eventually converges to full red, blue, green.
Processing 3.2.3, Windows 8, AMD A8, Acer E15.
The following sketch will demonstrate the problem.
void setup() {
size(500,300,P3D);
fill(255);
rect(0,0,250,300);
fill(0);
rect(250,0,250,300);
}
void draw() {
noStroke();
rectMode(CENTER);
if(mouseX > 250) {
fill(255,5);
rect(mouseX,mouseY,50,50);
} else {
fill(0,5);
rect(mouseX,mouseY,50,50);
}
rectMode(CORNER);
for(int i = 0; i <= 480; i+=5) {
int gray = (int)map(i, 0, 480, 0, 255);
noStroke();
fill(gray);
rect(i, 0, 20,40);
}
}
Isn't this _expected_ due to Zeno's Paradox + rounding?
Pixels are repeatedly washed with a low alpha -- each time getting 2% of the way closer to the target color. Initially that 2% step is 5, then 4, 3, 2, 1... The pixels never reach 100% value because, at a certain distance, the next step is so small that it drops below the rounding error. In this case that value is ~25 -- (25/255)*0.02 = .00019, so the color never gets darker than 25. Same math applied in the opposite direction means never getting whiter than 230 (255-25). If the alpha was a different value, change would converge and stop at a different distance.
Whether this is expected or not, here is a simple inspector based on your code. It stops and prints the result once repeated applications of the color no longer have an effect. Trying changing "alpha" to change the convergence point.
// Repeat Transparent Color Convergence
// https:// github.com/processing/processing/issues/4743
// blacker and whiter squares stall out at (25,25,25) and (230,230,230)
color c1, c2;
color prev1, prev2;
int alpha = 5;
void setup() {
size(400,200);
noStroke();
textAlign(CENTER,CENTER);
frameRate(15);
background(128);
}
void draw() {
// wash blacker
fill(0,alpha);
rect(0,0,width/2,height);
// wash whiter
fill(255,alpha);
// reference strip
rect(width/2,0,width,height);
for(int i = 0; i <= 480; i+=5) {
int gray = (int)map(i, 0, 480, 0, 255);
noStroke();
fill(gray);
rect(i, 0, 20,40);
}
// console inspector
c1 = get(width/4,height/2);
c2 = get(3*width/4, height/2);
println(red(c1),green(c1),blue(c1)," | ", red(c2),green(c2),blue(c2));
// stop when no longer changing
if(prev1 == c1 && prev2 == c2){
fill(255);
text(red(c1)+" "+green(c1)+" "+blue(c1),width/4,height/2);
fill(0);
text(red(c2)+" "+green(c2)+" "+blue(c2),3*width/4, height/2);
noLoop();
}
prev1 = c1;
prev2 = c2;
}

If you do the the same with transparent red, blue, green, the repeated painting eventually converges to full red, blue, green.
By the way, this would be an inconsistency if it was true, but it not true. Just change the test sketch to fill(255,0,0,alpha) -- you'll see that the red channel converges on (230,25,25).
By the way, this would be an inconsistency if it was true, but it not true. Just change the test sketch to fill(255,0,0,alpha) -- you'll see that the red channel converges on (230,25,25).
Ah! You are right. I thought for sure I confirmed that it did converge to full red/green/blue! Sorry about that.
Isn't this expected due to Xeno's Paradox + rounding?
Hmmm. I thought painting with 5/255 alpha means you add 5/255 over and over, until you hit the 255 ceiling.
What is the repeated operation that is happening on that initial transparent white that takes it from 130 to 230 and stay at 230? (reading from your print outs)
You shoud use blendMode(ADD) if you want additive blending. Default blending mixes the two colors as follows: result = dest * (1 - srcAlpha) + src * (srcAlpha) (where colors are mapped form 0-255 to 0.0-1.0).
Most helpful comment
You shoud use
blendMode(ADD)if you want additive blending. Default blending mixes the two colors as follows:result = dest * (1 - srcAlpha) + src * (srcAlpha)(where colors are mapped form 0-255 to 0.0-1.0).