Skip to content

[p5.js 2.0 Bug Report]: p5.strands BLUR filter having some trouble with alpha blending #8345

Description

@davepagurek

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • Build process
  • Unit testing
  • Internationalization
  • Friendly errors
  • Other (specify if possible)

p5.js version

2.2-rc2

Web browser and version

Chrome

Operating system

MacOS

Steps to reproduce this

Steps:

  1. Clear the background
  2. Draw something
  3. Apply filter(BLUR)

Currently it looks like this:

Image

If you use a white background instead of a clear one, it looks like this:

Image

I think this is a regression in the 2.2 RC after I converted filter shaders to p5.strands and updated how premultiplied alpha works.

Previously:

  • All textures coming into WebGL were premultiplied (so e.g. the red channel data you read in a shader is actually red * alpha, not just red)
  • We would generally manually un-multiply textures before passing data into p5.strands, letting users work in unmultiplied alpha like how colors in the rest of p5 work
  • We then multiply the resulting output color by alpha right at the end because we need to output premultiplied alpha
  • In the blur filter specifically, though, we skip p5.strandswe would read the premultiplied data directly, average the premultiplied samples, and return the result

Now:

  • All textures come in unmultiplied, eliminating the need for the manual unmultiplying step
  • We still do the multiplication again right at the end before rendering
  • The blur filter is now p5.strands, and so the blur samples come in unmultiplied. We average them unmultiplied, and then return that, and p5.strands automatically multiplies in the result after.

The main difference for the blur filter: before, samples were averaged with alpha multiplied in, and now they are averaged separately.

Since this used to work and now doesn't, I think that means we have to update the blur p5.strands filter to:

  • read the texture, and then average sample * [sample.a, sample.a, sample.a, 1] instead of just sample to do the averaging with alpha included
  • Return [avg.r / avg.a, avg.g / avg.a, avg.b / avg.a, avg.a] instead of just avg to still comply with p5.strands's expectation that you return unmultiplied colors

Snippet:

Live: https://editor.p5js.org/davepagurek/sketches/Ja7TcT9ia

async function setup() {
  await createCanvas(400, 400, WEBGL);
}

function draw() {
  clear();
  fill('red')
  noStroke();
  circle(0, 0, 100);
  filter(BLUR, 10);
}

Activity

  1. added this to the 2.2 milestone on Dec 18, 2025
  2. Piyushrathoree commented on Dec 19, 2025

    @Piyushrathoree
    Contributor

    hey hiii , I think this same thing is working properly on my side

    Image
  3. davepagurek commented on Dec 19, 2025

    @davepagurek
    ContributorAuthor

    Hi, sorry, comment out the background(255) in the sketch :)

  4. Piyushrathoree commented on Dec 19, 2025

    @Piyushrathoree
    Contributor

    ohk got it , could you please assign as well ?

  5. davepagurek commented on Dec 19, 2025

    @davepagurek
    ContributorAuthor

    You're still working on #8344 right? We generally try to have people just work on one thing at a time, but after that feel free to take this one on!

  6. Piyushrathoree commented on Dec 19, 2025

    @Piyushrathoree
    Contributor

    @davepagurek I have raised PR for #8344 , now could you please assign this one.

  7. Deepak-cell311 commented on Dec 21, 2025

    @Deepak-cell311

    @davepagurek
    Hi,
    It looks like the BLUR shader is now averaging unmultiplied texture samples without accounting for alpha after the move to p5.strands. Previously this worked because WebGL textures were premultiplied, so the blur math implicitly included alpha. With unmultiplied inputs, transparent pixels seem to be contributing color during the blur, which shows up when using clear(). It might be worth updating the blur shader to weight samples by sample.a during averaging and then un-multiply before returning, so the math matches the old behavior while still returning unmultiplied output for p5.strands.

    I think avg += weight * texture2D(tex0, sampleCoord); this line is a caused a issue, beacuse assumes a specific alpha format of the texture is no longer valid in p5.js 2.2-rc2.

    It can be solved by

    vec4 s = texture2D(tex0, sampleCoord);
    avg += weight * vec4(s.rgb * s.a, s.a);
    

    After a loop to ignore the runtime error

    avg /= total
    if (avg.a > 0.0) {
      avg.rgb /= avg.a;
    }
    
  8. Piyushrathoree commented on Dec 21, 2025

    @Piyushrathoree
    Contributor

    @davepagurek Hi, It looks like the BLUR shader is now averaging unmultiplied texture samples without accounting for alpha after the move to p5.strands. Previously this worked because WebGL textures were premultiplied, so the blur math implicitly included alpha. With unmultiplied inputs, transparent pixels seem to be contributing color during the blur, which shows up when using clear(). It might be worth updating the blur shader to weight samples by sample.a during averaging and then un-multiply before returning, so the math matches the old behavior while still returning unmultiplied output for p5.strands.

    I think avg += weight * texture2D(tex0, sampleCoord); this line is a caused a issue, beacuse assumes a specific alpha format of the texture is no longer valid in p5.js 2.2-rc2.

    It can be solved by

    vec4 s = texture2D(tex0, sampleCoord);
    avg += weight * vec4(s.rgb * s.a, s.a);
    

    After a loop to ignore the runtime error

    avg /= total
    if (avg.a > 0.0) {
      avg.rgb /= avg.a;
    }
    

    yeah , you're right thanks for it

  9. Deepak-cell311 commented on Dec 21, 2025

    @Deepak-cell311

    @Piyushrathoree
    Hi, are you currently working on this issue ?

  10. Piyushrathoree commented on Dec 21, 2025

    @Piyushrathoree
    Contributor

    @Piyushrathoree
    Hi, are you currently working on this issue ?

    Yup , and this is resolved , I was having some more thing to discuss that's why I didn't raise the PR , will be raising it in some time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions