Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webgl: white border when using transparency (alpha)

When rendering textures that have an alpha-channel, a white border appears around the non-transparent part (the border seems to be the pixels that have an alpha > 0 and < 1):

enter image description here

The original texture is created in illustrator and exported as a png. here it is:

enter image description here

(well, seems stackoverflow altered the image, adjusting pixels that are not completely opaque/transparent, so here is a link)

it is probably the blending, though i dont know what is wrong with the setup:

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

[Update]

Here is a rendered version, where i added a alpha-gradient to the left part of the texture (so it is getting from 0 opacity to 1 until the half)

enter image description here

this texture is the only texture rendered at this position. it seems to be whitest around a=0.5. really weird. the background is just a cleared color:

gl.clearColor(0.603, 0.76, 0.804, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// render objects here

the depth-function looks like:

gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);

any ideas? thanks a lot.

[Update 2]

Answering my own question: the effect occurs when the background-color of the canvas or the body of the html-page is white. I don't have an explanation, though.

like image 822
CodeSalad Avatar asked Oct 11 '11 21:10

CodeSalad


3 Answers

Use premultiplied alpha and this problem will go away.

See: http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BPremultiplied%20alpha%5D%5D

like image 62
Justin Larrabee Avatar answered Nov 20 '22 01:11

Justin Larrabee


This is problem related to texturing linear interpolation. On borders, some interpolated pixels will take half white half green, and 0.5 alpha. You should modify your texture to extend your borders with one more green pixel, even if it is totally transparent.

like image 44
neodelphi Avatar answered Nov 19 '22 23:11

neodelphi


What's your draw order? This looks like a depth buffering issue to me — you start with a white background, draw the thing with the border so that it's composited on the white, then draw the thing behind the thing with the border. Those areas where the border was blended with the original white background will have stored a value in the depth buffer equal to the depth of their plane, so when the object behind is subsequently drawn, its pixels are discarded in that area.

The general rule is to draw transparent objects after opaque objects, usually from back to front. If you're using additive blending then it's often good enough to disable the depth buffer after the opaque draw and draw them in any order.

like image 2
Tommy Avatar answered Nov 19 '22 23:11

Tommy