开发者

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):

webgl: white border when using transparency (alpha)

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

webgl: white border when using transparency (alpha)

(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);

[Upd开发者_JAVA百科ate]

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)

webgl: white border when using transparency (alpha)

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.


Use premultiplied alpha and this problem will go away.

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


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.


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.


When setting the FragColor in the shader, try multiplying the image RGB with the image alpha.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜