# P5js blendmode is so strange

**URL:** <https://discourse.processing.org/t/p5js-blendmode-is-so-strange/30958>\
**Category:** Coding Questions\
**Created:** [June 29, 2021, 7:53am UTC](https://discourse.processing.org/t/p5js-blendmode-is-so-strange/30958 "2021-06-29T07:53:36Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![yang](https://avatars.discourse-cdn.com/v4/letter/y/77aa72/32.png) [@yang](https://discourse.processing.org/u/yang)\
**Post date:** [June 29, 2021, 7:53am UTC](https://discourse.processing.org/t/p5js-blendmode-is-so-strange/30958/1 "2021-06-29T07:53:36Z")

</div>

Hello guys,I’m trying to make an animation of rains flowing down a window,https://editor.p5js.org/yangshuzhan/embed/F1cKA9Tko  
but there’s still some color left that doesn’t blend with the background.  
So I look up the blendMode() reference, and find a fomula for BLEND C = A_factor +B. This is so different from what I used to know. I think the typical one should be "C = A_factor + B\*(1-factor)" . Is there any way I can do to solve this issue? Please give me some instructions, I’m a beginner to p5 and javascript. 😀`

```auto
function setup() {
  createCanvas(400, 400);
  background(20, 255);
  rain1 = new Rain(100, 100);
  noStroke();
  blendMode(BLEND);
}
class Rain {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.radius = 20;
    this.age = 0;
  }
  show() {
    circle(this.x, this.y, this.radius);
  }
  move() {
    this.y += 1;
    this.x += noise(this.y) - 0.5;
    this.radius -= 0.01;
    this.age++;
  }
  // detect() {
  // loadPixels();
  // for (var i = -0.785; i <= 0.785; i += 0.1) {
  // if (get(x, y + radius * cos(i)) != color(20)) {
  // return true;
  // }
  // }
  // }
}
rains = [];

function draw() {
  background(20, 5);
  if (random(0, 1) < 0.01) {
    //出生
    rains.push(new Rain(random(0, 400), random(0, 400)));
  }
  for (var i = 0; i < rains.length; i++) {
    //批量绘制
    rains[i].move();
    rains[i].show();
    if (rains[i].age > 1000) {
      rains.splice(i, 1);
    }
  }
  // rain1.show();
  // rain1.move();
}

```

---

<div class="post-metadata">

**Author:** ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)\
**Post date:** [July 2, 2021, 2:58am UTC](https://discourse.processing.org/t/p5js-blendmode-is-so-strange/30958/2 "2021-07-02T02:58:45Z")

</div>

I don’t think this is a facet of p5.js per se. `BLEND` is the default blend mode and it maps directly to a [`CanvasRenderingContext2D.globalCompositeOperation`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) value of `source-over`. I believe that the residual color that never quite goes away has to do with the math that is used to combine colors with alpha values. If you want to avoid the residual streaks, while maintaining the same rate of fade you could double the alpha value for your call to `background()` but only call it every other frame.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/soegaard/32/13657_2.png) [@soegaard](https://discourse.processing.org/u/soegaard)\
**Post date:** [July 3, 2021, 10:20am UTC](https://discourse.processing.org/t/p5js-blendmode-is-so-strange/30958/3 "2021-07-03T10:20:27Z")

</div>

I went down the rabbit hole.

As KumuPaul says P5.js simply sets the compostion operation of an HTML 5 canvas (See [1]).  
The specification of the blending operations are given in [2].  
In the P5 source code BLEND is defined in [3] as “source-over”.  
The souce-over formulas are:

```
Fa = 1; Fb = 1 – αs
co = αs x Cs + αb x Cb x (1 – αs)
αo = αs + αb x (1 – αs)

```

See [2] for an explanation.

And as yang mentioned the middle formula shows not B but B\*(1-factor).  
So I think the formula in the P. and P5js references is a bit simplistic.  
Maybe on purpose - but confusing nevertheless.

FWIW the Source for P. contains a Java implementation of the blend operations, see [4].  
The blend\_blend function implements the default source over operation.

[1] [p5.js/p5.Renderer2D.js at 374acfb44588bfd565c54d61264df197d798d121 · processing/p5.js · GitHub](https://github.com/processing/p5.js/blob/374acfb44588bfd565c54d61264df197d798d121/src/core/p5.Renderer2D.js#L247)

[2] [Compositing and Blending Level 1](https://drafts.fxtf.org/compositing-1/#blending)

[3] [p5.js/constants.js at 374acfb44588bfd565c54d61264df197d798d121 · processing/p5.js · GitHub](https://github.com/processing/p5.js/blob/374acfb44588bfd565c54d61264df197d798d121/src/core/constants.js#L451)

[4]

> <https://github.com/processing/processing/blob/a6e0e227a948e7e2dc042c04504d6f5b8cf0c1a6/core/src/processing/core/PImage.java#L2482>

---

<div class="post-metadata">

**Author:** ![yang](https://avatars.discourse-cdn.com/v4/letter/y/77aa72/32.png) [@yang](https://discourse.processing.org/u/yang)\
**Post date:** [July 5, 2021, 5:37am UTC](https://discourse.processing.org/t/p5js-blendmode-is-so-strange/30958/4 "2021-07-05T05:37:24Z")

</div>

Thank you so much for your detailed reply. As KumuPaul suggested I doubled the alpha value, but the problem even become worse. Perhaps I’ll find a way to bypass the alpha and blendmode. 😅

---

<div class="post-metadata">

**Author:** ![atagger](https://avatars.discourse-cdn.com/v4/letter/a/d6d6ee/32.png) [@atagger](https://discourse.processing.org/u/atagger)\
**Post date:** [July 11, 2021, 7:39pm UTC](https://discourse.processing.org/t/p5js-blendmode-is-so-strange/30958/5 "2021-07-11T19:39:43Z")

</div>

Why don’t you just use lerpColor?

```auto
https://p5js.org/reference/#/p5/lerpColor

```

Use the age variable as the map and go from filling the rain drop color to fading into the background color. The blend mode is not going to do what you want, it is not like photoshop.

---

<div class="post-metadata">

**Author:** ![yang](https://avatars.discourse-cdn.com/v4/letter/y/77aa72/32.png) [@yang](https://discourse.processing.org/u/yang)\
**Post date:** [July 12, 2021, 3:01pm UTC](https://discourse.processing.org/t/p5js-blendmode-is-so-strange/30958/6 "2021-07-12T15:01:41Z")

</div>

Thanks for your advice! Do you mean I should save the trail of a raindrop in an array, and change the color every frame until they fade into background? Or I could change every pixel that aren’t background but the computation seems a bit heavy 🤪. I have no idea why p5 draws the background so fast ,but thank you anyway.

---

<div class="post-metadata">

**Author:** ![atagger](https://avatars.discourse-cdn.com/v4/letter/a/d6d6ee/32.png) [@atagger](https://discourse.processing.org/u/atagger)\
**Post date:** [July 12, 2021, 5:02pm UTC](https://discourse.processing.org/t/p5js-blendmode-is-so-strange/30958/7 "2021-07-12T17:02:00Z")

</div>

Yes you could use an array and push the circles / rain drop object to it. Without knowing your project it’s hard to say what’s best, but p5 can handle arrays of objects pretty well depending on what else is going on in your program. The blend mode itself is going to be computation heavy. You could also try to make the rain not a trail, but use a line or something and have them overlay everything like a particle system, but I don’t know what you are trying to accomplish. Just a suggestion.
