webgl:使用透明度(alpha)时的白色边框
渲染具有 alpha 通道的纹理时,非透明部分周围会出现白色边框(边框似乎是 alpha > 0 且 < 1 的像素):
原始纹理在 illustrator 中创建并导出为 png。这是:
(嗯,似乎 stackoverflow 改变了图像,调整不完全不透明/透明的像素,所以这里有一个链接)
它可能是混合,虽然我不知道设置有什么问题:
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
[更新]
这是渲染版本,我在纹理的左侧部分添加了 alpha 渐变(因此它从 0 开始)不透明度为 1 直到一半)
此纹理是渲染的唯一纹理这个位置。它似乎在 a=0.5 左右最白。真的很奇怪。背景只是一个清晰的颜色:
gl.clearColor(0.603, 0.76, 0.804, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// render objects here
深度函数看起来像:
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
有什么想法吗?多谢。
[更新 2]
回答我自己的问题:当画布的背景颜色或 html 页面的正文为白色时会出现该效果。不过我没有解释。
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):
The original texture is created in illustrator and exported as a png. here it is:
(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)
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用预乘阿尔法,这个问题就会消失。
请参阅:http://home.comcast .net/~tom_forsyth/blog.wiki.html#%5B%5BPremultiplied%20alpha%5D%5D
Use premultiplied alpha and this problem will go away.
See: http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BPremultiplied%20alpha%5D%5D
这是与纹理线性插值相关的问题。在边界上,一些插值像素将采用半白半绿和 0.5 alpha。您应该修改纹理,以再增加一个绿色像素来扩展边界,即使它是完全透明的。
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.
在着色器中设置 FragColor 时,尝试将图像 RGB 与图像 alpha 相乘。
When setting the FragColor in the shader, try multiplying the image RGB with the image alpha.