Compositing layers and alpha blending

Hi,

I have a diagram whose nodes consist of a Node with a Picture inside. The image is generated using WebGL, and drawImage is used to place it in the 2D context of the Picture’s element. I use zOrder to establish a relative layer order among nodes where that matters. Everything is basically working fine.

The images have an alpha component that is used to anti-alias the edges of what’s drawn. The issue I’m having is an unusual behavior as I drag images over one another, namely, where the upper layer has some transparency due to alpha, and if the colors (rbg components) of the layers are too similar in the region of transparency, then the pixels that should be alpha-blended instead become black, as if to enhance the edge contrast. I can see the behavior most clearly with this kind of test: I create say a green circle at zOrder = 0. I then create a gradient rectangle that changes from green to red, at zOrder = -1. As I drag the gradient behind the circle, when there is green/red overlap at the edge of the circle, the alpha blending works as expected. When there is red/red overlap at the edge of the circle, the pixels that are anti-aliased (have alpha less than full scale) turn black, so that the very edge of the circle turns black.

I can imagine this happening in response to overflow in the red component somehow (spilling over?) Or I can imagine a kind of color-dodging compositing mode being used on purpose. In any event, I’m wondering if (a) you know what might be causing this, and (b) how I might turn it off in favor of ordinary color-blind alpha blending.

Thanks,

-Luddy

Do you have a small screenshot showing the problem?

I’m not sure we have much control over how compositing is done. We can look into this tomorrow.

GOJS2

This shot shows a second form of the behavior, perhaps an additional clue? Note the black pixels in the lower left corner around the red band. Then, at the top right, there are more black pixels; this second form occurs where the overlap occurs near the boundary of the background image itself, irrespective of its color in that neighborhood.

GOJS3

Here’s a second shot that shows the gradient placed behind such that neither artifact occurs.

I found the problem with this help of this web page: https://limnu.com/webgl-blending-youre-probably-wrong/. In a word, I was generating images from WebGL with alpha values that were incorrect for subsequent compositing.

The author says that the usual alpha blending function

gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

results in an image whose transparency is wrong for subsequent compositing, exactly what’s going on when using drawImage() to transfer a WebGL result to a Picture and then layering the result. The author suggests:

gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);

for generation of images intended for subsequent compositing. And in my case, it does the trick! No more artifacts, at least in Firefox.

GOJS4

I’m still slogging through the math of the GL blend equations to try to understand this in detail. In any case, though, this issue can be closed, as I don’t see any indication that it has to do with GoJS per se.

-Luddy

That explanation makes sense. I’m glad you figured it out.