gecko-dev/gfx/wr/webrender/res/pf_vector_cover.glsl

78 строки
2.6 KiB
GLSL

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include shared
#ifdef WR_VERTEX_SHADER
in ivec4 aTargetRect;
in ivec2 aStencilOrigin;
in int aSubpixel;
in int aPad;
out vec2 vStencilUV;
flat out int vSubpixel;
void main(void) {
vec4 targetRect = vec4(aTargetRect);
vec2 stencilOrigin = vec2(aStencilOrigin);
vec2 targetOffset = mix(vec2(0.0), targetRect.zw, aPosition.xy);
vec2 targetPosition = targetRect.xy + targetOffset;
vec2 stencilOffset = targetOffset * vec2(aSubpixel == 0 ? 1.0 : 3.0, 1.0);
vec2 stencilPosition = stencilOrigin + stencilOffset;
gl_Position = uTransform * vec4(targetPosition, aPosition.z, 1.0);
vStencilUV = stencilPosition;
vSubpixel = aSubpixel;
}
#endif
#ifdef WR_FRAGMENT_SHADER
#define LCD_FILTER_FACTOR_0 (86.0 / 255.0)
#define LCD_FILTER_FACTOR_1 (77.0 / 255.0)
#define LCD_FILTER_FACTOR_2 (8.0 / 255.0)
in vec2 vStencilUV;
flat in int vSubpixel;
/// Applies a slight horizontal blur to reduce color fringing on LCD screens
/// when performing subpixel AA.
///
/// The algorithm should be identical to that of FreeType:
/// https://www.freetype.org/freetype2/docs/reference/ft2-lcd_filtering.html
float lcdFilter(float shadeL2, float shadeL1, float shade0, float shadeR1, float shadeR2) {
return LCD_FILTER_FACTOR_2 * shadeL2 +
LCD_FILTER_FACTOR_1 * shadeL1 +
LCD_FILTER_FACTOR_0 * shade0 +
LCD_FILTER_FACTOR_1 * shadeR1 +
LCD_FILTER_FACTOR_2 * shadeR2;
}
void main(void) {
ivec2 stencilUV = ivec2(vStencilUV);
float shade0 = abs(TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(0, 0)).r);
if (vSubpixel == 0) {
oFragColor = vec4(shade0);
return;
}
vec3 shadeL = abs(vec3(TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(-1, 0)).r,
TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(-2, 0)).r,
TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(-3, 0)).r));
vec3 shadeR = abs(vec3(TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(1, 0)).r,
TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(2, 0)).r,
TEXEL_FETCH(sColor0, stencilUV, 0, ivec2(3, 0)).r));
oFragColor = vec4(lcdFilter(shadeL.z, shadeL.y, shadeL.x, shade0, shadeR.x),
lcdFilter(shadeL.y, shadeL.x, shade0, shadeR.x, shadeR.y),
lcdFilter(shadeL.x, shade0, shadeR.x, shadeR.y, shadeR.z),
1.0);
}
#endif