0
kernel vec4 custom(__sample s1, __sample s2) {
            if(s1.a == 0.0)
                return s2;
            if(s2.a == 0.0)
                return s1;
            vec4 res;
            float temp = 1.0 - s2.a;
            res.rgb = s2.rgb * s2.aaa + s1.rgb  * (temp, temp, temp);
            res.a = 1.0;
            return res;
}

I am trying to merge 2 images, but have artifacts in bounds, where due to aliasing the pixels have less than 1 alpha. Is there any suggestions what I am doing wrong :/ For example the cheeks have some kind of bound, which doesn't appear if I place one over the other via UIImageViews

cheek

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Vahe Karamyan
  • 33
  • 1
  • 10

1 Answers1

2

OpenGL ES uses post-multiplied alpha, which means that channels are blended independently, but which is inaccurate for a lot of blending operations.

Imagine blending a source fragment [1.0, 0.0, 0.0, 0.5] (red, half transparent) on to a destination framebuffer [0.0, 0.0, 1.0, 0.0] (blue, fully transparent). You would logically expect "half transparent red" as the original destination color is not visible due to the 0.0 alpha value. However, because the channels are blended independently you would end up with the final RGB color being purple [0.5, 0.0, 0.5].

The fast way to fix this is by propagating the color values out into the transparent region, so that the opaque pink color extends out in to the feather region where you start to fade it out.

A better way to fix this is using pre-multipled alpha, but that starts to have side-effects (loss of precision in texel storage, and you need a different blend equation).

solidpixel
  • 10,688
  • 1
  • 20
  • 33
  • Another option is to use [programmable blending](https://developer.apple.com/library/content/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/BestPracticesforShaders/BestPracticesforShaders.html#//apple_ref/doc/uid/TP40008793-CH7-SW23) so you can control the entire blend equation yourself. – rickster Oct 20 '17 at 17:53