在OpenGL中使用RGB纹理作为alpha值/亚像素字体渲染

3

我目前正在使用FreeType进行子像素模式,并将每个像素的最大颜色作为alpha值,使用以下片段着色器:

    uniform sampler2D Image;
    uniform vec4 Color;

    smooth in vec2 vVaryingTexCoord;

    out vec4 vFragColor;

    void main(void){
        vec4 color = texture(Image, vVaryingTexCoord);
        vFragColor = color * Color;
    }

这适用于深色背景,但在浅色背景下会显示边框像素(例如当一个文本像素是(1,0,0)时)。要使其与更明亮的背景配合使用,我需要传递背景颜色并自己进行混合,这一步骤在移动到更复杂的背景时开始失效。
有没有一种方法可以将FreeType中的RGB值用作实心颜色的alpha值(传递给着色器)?基本上这个公式,其中b =背景像素,t =当前文本像素,c =静态颜色:
b*((1,1,1) - t) + t*c.rgb*c.a

我认为先绘制其他所有内容,然后将该帧缓冲传递给字体着色器会起作用,但这似乎有点过度设计。在OpenGL混合阶段中有没有一种方法可以做到这一点?我尝试了一些glBlendFunc等操作,但没有任何进展。


根据我的经验,这是一个难以解决的问题。你的结论和我的一样。我最终放弃了。你可以尝试通过在文本周围创建光晕并将其与背景颜色混合来“强制”设置背景颜色。至于OpenGL混合阶段,我的直觉是“无法完成”。 - Andreas
FreeType shader(请看大约结尾处)展示了从纹理中使用 maxmin 作为 alpha,并在着色器中计算混合。 - Ripi2
1个回答

4

使用自OpenGL 3.3以来就可用的双源混合技术,可以实现。甚至这份规范草案都提到了亚像素渲染作为用例。只需完成以下操作即可使其正常工作:

glBlendFunc(GL_SRC1_COLOR, GL_ONE_MINUS_SRC1_COLOR);

不要忘记启用GL_BLEND,这常常发生在我身上 :D

在片元着色器中指定双输出:(如果您愿意,也可以按名称绑定,请参见规范)

layout(location = 0, index = 0) out vec4 color;
layout(location = 0, index = 1) out vec4 colorMask;

在主函数中:

color = StaticColor;
colorMask = StaticColor.a*texel;

其中StaticColor是全局文本颜色统一变量,而texel是字形的当前像素值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接