ios - 为什么纹理表面的透明和不透明区域之间存在暗边/光晕(在 opengl es 2.0 片段着色器中)

标签 ios png transparency glsl opengl-es-2.0

我正在使用 PNG 纹理图像来控制 Opengl es 2.0 着色器(在 iOS 上)中片段的不透明度。我想要的结果是场景中灰色背景之上的浅灰色文本(片段着色器应用于场景中的三角形带)。问题是我的文字周围有黑边——它们看起来像人工制品。我对 alpha 信息使用 PNG 透明度——但我对其他方法持开放态度。这是怎么回事,我该如何正确执行此操作?

最佳答案

首先,看看这个关于 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/

相关文章:

ios - 为什么 XCode 和 instruments 内存使用之间存在巨大差异,这可以吗?

iphone - 在设备中启动项目时出现问题

iphone - 在 iOS 上使用 Phonegap 将图像转换为 Base64 字符串

java - 如何从 Android (Java) 中的位图中读取元数据?

R 谷歌地图,添加更长的路径

opengl - 加载到纹理上时 png 图像模糊

node.js - 如何使用 NodeJS 和 GraphicsMagick 剪切图像的透明部分

c# - 单击 Visual C# 窗口窗体的透明度?

image - Golang 使 RGBA 图像显示奇怪的颜色

ios - 界面中的未知类 FBLoginView