BradLarson / GPUImage

An open source iOS framework for GPU-based image and video processing
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
BSD 3-Clause "New" or "Revised" License
20.25k stars 4.61k forks source link

BUG in GPUImageNormalBlendFilter #1102

Open EliSchleifer opened 11 years ago

EliSchleifer commented 11 years ago

If I specify a color like r:255 g:0 b:0 alpha:0.5 it blends nicely. If I specify all white the blend just overwrites everything with white.

    GPUImagePicture * source =[[GPUImagePicture alloc] initWithImage:viewImage];

    GPUImageFastBlurFilter * blur = [[GPUImageFastBlurFilter alloc] init];
    [blur setBlurPasses:5];
    [source addTarget:blur];

    GPUImageSaturationFilter * desaturate = [[GPUImageSaturationFilter alloc] init];
    [desaturate setSaturation:.1];
    [blur addTarget:desaturate];

    GPUImageSolidColorGenerator * white = [[GPUImageSolidColorGenerator alloc] init];
    [white setColorRed:255 green:255 blue:255 alpha:.5];
    [white forceProcessingAtSize:self.frame.size];

    GPUImageNormalBlendFilter * blend = [[GPUImageNormalBlendFilter alloc] init];

    [desaturate addTarget:blend];
    [white addTarget:blend];

    [source processImage];

    blurredImage = [blend imageFromCurrentlyProcessedOutput];
BradLarson commented 11 years ago

The normal blend math is as follows:

 lowp float a = c1.a + c2.a * (1.0 - c1.a);
 outputColor.r = (c1.r * c1.a + c2.r * c2.a * (1.0 - c1.a))/a;
 outputColor.g = (c1.g * c1.a + c2.g * c2.a * (1.0 - c1.a))/a;
 outputColor.b = (c1.b * c1.a + c2.b * c2.a * (1.0 - c1.a))/a;
 outputColor.a = a;

c1 is the second image's color. When that is 1.0, 1.0, 1.0, with an alpha of 0.5, you start with 0.5, then add 0.5 * the color channel in the first image. This is going to start you near the top of the color range, close to white. Are you sure your image is completely white, and not just very close to being completely white?

It is possible that the lowp precision qualifier isn't providing the correct dynamic range needed here, so you could try replacing the lowp precisions throughout that fragment shader with mediump.

EliSchleifer commented 11 years ago

Thanks Brad. Love the stack by the way. I am totally digging the power but a little behind on the OpenGL texture world as it were.

1) Should the values to SolidColorGenerator all by floats so white would be 1.0,1.0,1.0 as opposed to 255,255,255?

2) I am looking to achive a blend like this kCGBlendNormal where I paint a fill rectangle of white with alpha .5 onto the context. Is the normal blend in GPUImage not the right tool?

Thanks