Использовать RGB-текстуру в качестве альфа-значений / рендеринг субпиксельного шрифта в OpenGL

В настоящее время я использую FreeType в субпиксельном режиме и принимаю самый большой цвет каждого пикселя в качестве альфа-значения со следующим фрагментным шейдером:

    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)). Чтобы заставить его работать с более яркими фонами, мне нужно было бы передать цвет фона и выполнить смешивание самостоятельно, которое начинает разрушаться, когда я перехожу к более сложным фонам.

Есть ли способ использовать значения RGB из FreeType в качестве альфа-значений для сплошного цвета (который передается шейдеру)? Эта формула в основном, где b = фоновый пиксель, t = текущий текстовый пиксель, c = статический цвет:

b*((1,1,1) - t) + t*c.rgb*c.a

Я думаю, что рисование всего остального в первую очередь и передача этого кадрового буфера в шейдерный шрифт будет работать, но это кажется немного излишним. Есть ли способ сделать это на этапе смешивания OpenGL? Я пытался поиграться с glBlendFunc и тому подобным, но ничего не получилось.

1 ответ

Решение

Это возможно, используя Dual Source Blending, доступный начиная с 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 - текущее значение пикселя глифа.

Другие вопросы по тегам