processing / p5.js

p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. http://twitter.com/p5xjs —
http://p5js.org/
GNU Lesser General Public License v2.1
21.5k stars 3.29k forks source link

background with alpha unexpected behavior #7065

Closed jacopomazzoni closed 4 months ago

jacopomazzoni commented 4 months ago

Most appropriate sub-area of p5.js?

p5.js version

1.9.3

Web browser and version

Brave ( chrome ) 1.66.110 Chromium: 125.0.6422.60 (Official Build) (64-bit)

Operating system

Windows/MacOSX

Steps to reproduce this

Actual Behavior

for alpha values < 25 in background some shapes are never fully overwritten

ie: background(0,5) has the issue background(0,25) does not

Expected Behavior

any shape after a certain amount of frames depending on its color should be wiped away by enough overlays no matter how small the transparency

Steps to reproduce

Steps:

  1. run this MRE and look at the circle never disappearing
  2. change values and observe that ~25 depending on browser and os is the threshold value for shapes finally disappearing
  3. fix implementation?

    Snippet:

// https://editor.p5js.org/jacopom/sketches/RU0kHMjnG function setup() { createCanvas(400, 400); background(0);

}

function draw() {

background(0,5); fill(255); stroke(255); if(frameCount == 1 ) { ellipse(width/2,height/2,100); } fill(0); rect(0,0,100,30); fill(255); text("Frame: " + frameCount,20,20);

// / 5 out of 255 alpha / / expected behaviour 255/5 = 51 / / in 51 cycles a white value of / / 255 should be reduced to 0 / / let's test it! / / in reality for any value <~25 this does not happen / / and a faint white dot remains visible forever / // }

davepagurek commented 4 months ago

Hi! Unfortunately this isn't an issue p5 is able to fix, as it is an issue with the data representation of all js canvases.

The first issue is that the color doesn't get reduced by 5/255 each frame. Instead, it's something closer to prevColor * 250/255 + 0 * 5/255. However, the colors are all stored as integers, so the new color is actually round(prevColor * 250/255). When the color gets dark enough, round(prevColor * 250/255) just equals prevColor and it stops changing.

So, some workarounds: