我正在使用PNG纹理图像来控制Opengl es 2.0着色器(在iOS上)中片段的不透明度。我得到的结果是场景的中等灰色背景之上的浅灰色文本(片段着色器应用于场景中的三角带)。问题是我的文字周围有黑边-它们看起来像文物。我正在使用PNG透明度获取Alpha信息-但我愿意接受其他方法。这是怎么回事,我该如何正确执行此操作?
最佳答案
首先,请查看有关PNG transparency and premultiplied alpha.长话短说的答案,长话短说,PNG图像中不透明度小于100%的像素将被预乘,因此实际上它们随着变得更加透明而越来越暗。因此,边缘周围的深色伪影。
即使没有PNG和预乘透明度,如果忘记在应用透明度之前设置片段着色器的颜色,您仍然可能会遇到问题。
解决此问题的方法(您希望文本为浅灰色,并且纹理贴图中的所有非文本都是透明的)将创建一个纹理贴图,其中文本为白色,背景为黑色。
此纹理贴图将控制片段的alpha。片段的RGB值将设置为浅灰色。
例如:
// color used for text
lowp vec4 textColor = vec4(.82,.82,.82,1.0);
gl_FragColor = textColor;
// greyscale texture passed in as uniform
lowp vec4 alphaMap = texture2D(u_alpha_texture,v_texture);
// set the alpha using the texture
gl_FragColor.w = alphaMap.x;
在您的颜色纹理变化的情况下,此方法将需要两个单独的纹理贴图图像(一个用于颜色,一个用于alpha)。显然,这要比处理具有嵌入的Alpha透明度的PNG效率低。但是,以我的经验,这是一个很好的权衡(处理预乘像素可能会违反直觉,而其他无需预乘即可加载PNG透明度的方法也会增加复杂性)。
这种方法的好处是,您可以独立于纹理贴图图像而更改文本的颜色。例如,如果您想要红色文本,则可以将textColor值更改为:
lowp vec4 textColor = vec4(1.0,0.0,0.0,1.0);
您甚至可以随时间改变颜色等,而与alpha无关。这就是为什么我觉得这种方法很灵活。
关于ios - 为什么在带纹理的表面的透明区域和不透明区域之间存在深色边缘/光晕(在opengl es 2.0片段着色器中),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7841450/