OpenGL:模糊文本周围的黑暗光环

时间:2015-02-21 18:33:11

标签: opengl alphablending

我正在渲染绿色文字,其中一些是模糊的,带有一个坚实的蓝色背景。透明度功能按预期工作,但我得到了一个黑暗的光环"在文本的模糊区域。我花了几天时间阅读文章并尝试不同的解决方案,但无济于事。

前景图像用纯绿色(0,0,1)填充,alpha通道用于定义文本和透明度。

访问网站http://www.andersriggelsen.dk/glblendfunc.php并输入以下两个图片网址

,可以轻松证明我的问题

前景:http://troikatronix.com/files/text320x240.png

背景:http://troikatronix.com/files/solid-blue.png

此图显示了设置和带有暗晕的结果图像。

transparency problem example

为了试图深入研究,我编写了一个调试函数,用于在渲染每个图层后回读后缓冲区。在数字上,数学都是正确的。

例如,如果我以10%的比例渲染预乘的源图像的实体部分(例如,在使用10%的预乘之前,源是rgba [0,0,255,255])并使用glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA)它就像这样

bkg = rgba[0, 0, 255, 255]
src = rgba[0, 25, 0, 25]
result = rgba[0, 25, 230, 255]

但是当你看到它时,你基本上会看到一个黑色的蓝色,看不到绿色,正如这个图像所示

darkened blue text

那么我做错了什么?或者这是某种伽玛/色彩匹配问题,其中绿色的增加不像蓝色的减少那么明显?

1 个答案:

答案 0 :(得分:3)

这是一个简单的感知问题,它与伽玛有关。

从此裁剪输出开始:
original
如果你拆分频道,你会得到(红色,绿色,蓝色):
 red green blue
监视器,包括您几乎肯定会看到的sRGB LCD监视器,对像素值进行伽玛缩放 note 1

以下是sRGB伽马函数 注2 的近似图: gamma correction; source: Wikimedia

当我们查看蓝色背景(值0,0,255 => 0,0,1)时,我们会得到0,0,1的输出。同样地,当我们看到字母内部的完全绿色时,我们得到明显的亮度0,1,0 注3

现在想想边缘点上会发生什么。假设它基本上位于中间0,127,128〜=> 0.0,0.5,0.5。使用图表,我们得到了0.00,0.218,0.218的输出表观强度。我们对像素亮度的感知在各个通道上是相加的,因此我们得到的整体亮度为0.436

这明显比字母的内部或外部更暗 - 你觉得它是一个黑暗的乐队!


注1 为什么?它具有从例如改变它的效果。 200201实际亮度大于562.4。我们这样做是因为人类对比度感知基本上是百分比差异的函数。 为了保持明显均匀的对比度,亮度必须是非线性的。
note 2 现实情况有点不同,但这基本上是正确的。具体来说,指数实际上是0.0,并且由于数值原因它变为线性接近{{1}}。有时会有进一步的修正使C1连续。
note 3 不同的颜色通道也会缩放,以提供相似的视在亮度。