fredsa / forplay

Automatically exported from code.google.com/p/forplay
Apache License 2.0
12 stars 4 forks source link

WebGL alpha blending is incorrect (premultiplied alpha issue) #49

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
We're still not calculating alpha blending correctly. In the attached image: 
left is WebGL, right is Canvas. Notice the dark line when blending from 
transparent to white.

Due to stability issues, specifying premultiplied alpha at the webgl attribute 
level isn't an option. I think the best route is to do this ourselves in code 
(e.g., gl.blendFunc(ONE, INVERSE_ALPHA) and premultiply the color channels when 
loading the image).

Original issue reported on code.google.com by pdr@google.com on 19 Jun 2011 at 8:37

Attachments:

GoogleCodeExporter commented 9 years ago
I'm getting closer on this issue... I think this applies to all scenarios where 
we blit one gl texture onto a another. We do this when we rescale a texture up 
to a power of two texture in GL, and when we call drawImage on a Surface.

Original comment by spinf...@gmail.com on 4 Jul 2011 at 12:58

GoogleCodeExporter commented 9 years ago
@pdr: What's the code look like to create this image? It's a bit hard to guess 
what problems might be creeping in without knowing the order of operations.

@spinf... (Is that you too, Philip?): To see if it's related to pow2 texture 
resampling, either turn off repeats or pre-sample the source texture to pow2. 
Of course, if you have to use a SurfaceLayer to get this effect, then you're 
still rendering to an FBO, so that could still be the problem.

Original comment by jgw@google.com on 4 Jul 2011 at 1:13

GoogleCodeExporter commented 9 years ago
Oops, wrong account--yeah spinf... is me. You can see this issue and the code 
behind it in the new manual tests project here: 
http://forplay-code-reviews.appspot.com/18001. The image used is different but 
the dark halos are the same. By the way--my comment at the start of this issue 
is incorrect. We're calculating premultiplied alpha correctly on everything but 
the repeat texture and surface drawImage cases.

The issue only appears when we modify a texture; Images work beautifully.

I compared the code path of creating/drawing an image vs drawImage in Surface 
and they look to be equivalent. Similarly for pow2texture. I confirmed that the 
pow2 code is problematic by always calculating a pow2 texture for each image 
(if true || repeatX || repeatY), and the dark halos appeared on all my images.

I'll be offline and onlake for the rest of today, but any tips would be great. 
I'll be jumping back in and figuring this out tomorrow.

Original comment by pdr@google.com on 4 Jul 2011 at 1:48

GoogleCodeExporter commented 9 years ago
I think this issue is caused by the fact that when Surface or pow2texture is 
used, we first render to a texture and after that render the texture to the 
framebuffer. This causes all the alpha multiplications to be done twice and 
that causes alpha values between 0 and 1 to break.

I got the pow2texture part fixed by setting blendFunc(ONE, ZERO) just before we 
draw to the texture and back to blendFuncSeparate(SRC_ALPHA, 
ONE_MINUS_SRC_ALPHA, SRC_ALPHA, DST_ALPHA) right after the texture is ready.

With Surfaces we need to do something similar but since there we can draw a lot 
of things to one texture, we can't just disable blending, but a more 
sophisticated blendFunc is needed.

Original comment by markus.k...@rovio.com on 30 Aug 2011 at 12:08