wel*_*urm 3 opengl font-rendering
目前,我在子像素模式下使用 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;
}
Run Code Online (Sandbox Code Playgroud)
这对于深色背景效果很好,但在浅色背景上会显示边框像素(例如,当文本像素为 (1,0,0) 时)。为了使其适用于更明亮的背景,我需要传递背景颜色并自己进行混合,一旦我转向更复杂的背景,混合就会开始崩溃。
有没有办法使用 FreeType 中的 RGB 值作为纯色的 alpha 值(传递给着色器)?这个公式基本上是这样的,其中 b = 背景像素,t = 当前文本像素,c = 静态颜色:
b*((1,1,1) - t) + t*c.rgb*c.a
Run Code Online (Sandbox Code Playgroud)
我认为先绘制其他所有内容并将帧缓冲区传递给字体着色器会起作用,但这似乎有点过大了。有没有办法在 OpenGL 混合阶段做到这一点?我尝试使用 glBlendFunc 等,但没有取得任何进展。
可以使用自 OpenGL 3.3 起可用的双源混合。该规范草案甚至提到了子像素渲染作为用例。使其工作所需的一切:
glBlendFunc(GL_SRC1_COLOR, GL_ONE_MINUS_SRC1_COLOR);
Run Code Online (Sandbox Code Playgroud)
(别忘了启用 GL_BLEND,我经常遇到这种情况 :D)
在片段着色器中指定双输出:(如果需要,您可以按名称绑定,请参阅规范)
layout(location = 0, index = 0) out vec4 color;
layout(location = 0, index = 1) out vec4 colorMask;
Run Code Online (Sandbox Code Playgroud)
主要内容:
color = StaticColor;
colorMask = StaticColor.a*texel;
Run Code Online (Sandbox Code Playgroud)
其中StaticColor是全局文本颜色统一,texel是字形的当前像素值。