msdf subpixel rendering v1 - PaintLab/PixelFarm GitHub Wiki
please comment on this,
I modified the original msdf glsl shader (https://github.com/Chlumsky/msdfgen) [left] to archive font subpixel rendering effect.[right]
the original look like this :
#ifdef GL_OES_standard_derivatives
#extension GL_OES_standard_derivatives : enable
#endif
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D s_texture; //msdf texture
uniform vec4 bgColor;
uniform vec4 fgColor;
float median(float r, float g, float b) {
return max(min(r, g), min(max(r, g), b));
}
void main() {
vec4 sample = texture2D(s_texture, v_texCoord);
float sigDist = median(sample[0], sample[1], sample[2]) - 0.5;
float opacity = clamp(sigDist/fwidth(sigDist) + 0.5, 0.0, 1.0);
gl_FragColor = mix(bgColor, fgColor, opacity);//original
}
I modified it to this :
#ifdef GL_OES_standard_derivatives
#extension GL_OES_standard_derivatives : enable
#endif
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D s_texture; //msdf texture
uniform vec4 bgColor;
uniform vec4 fgColor;
float median(float r, float g, float b) {
return max(min(r, g), min(max(r, g), b));
}
void main() {
vec4 sample = texture2D(s_texture, v_texCoord);
float sigDist = median(sample[0], sample[1], sample[2]) - 0.5;
float opacity = clamp(sigDist/fwidth(sigDist) + 0.5, 0.0, 1.0);
//gl_FragColor = mix(bgColor, fgColor, opacity);//original
float ddx= dFdx(sigDist);
if(opacity == 1.0){
//100%
gl_FragColor = mix(bgColor, fgColor, opacity);//original
}else if(opacity< (1.0/3.0)){
if(ddx>0.0){
//uphill
float c_r = bgColor[0];
float c_g = bgColor[1];
float c_b = (mix(bgColor[2],fgColor[2], opacity));
gl_FragColor = mix(bgColor, vec4(c_r,c_g,c_b,1.0), opacity);
}else{//downhill
float c_r = (mix(bgColor[0],fgColor[0], opacity));
float c_g = bgColor[1];
float c_b = bgColor[2];
gl_FragColor = mix(bgColor, vec4(c_r,c_g,c_b,1.0), opacity);
}
}else if(opacity< (2.0/3.0)){
if(ddx>0.0){
//uphill
float c_r = bgColor[0];
float c_g = (mix(bgColor[1],fgColor[1], opacity));
float c_b = (mix(bgColor[2],fgColor[2], 1.0));
gl_FragColor = mix(bgColor, vec4(c_r,c_g,c_b,1.0), opacity);
}else{//downhill
float c_r = (mix(bgColor[0],fgColor[0], 1.0));
float c_g = (mix(bgColor[1],fgColor[1], opacity));
float c_b = bgColor[2];
gl_FragColor = mix(bgColor, vec4(c_r,c_g,c_b,1.0), opacity);
}
}else{
if(ddx>0.0){
//uphill
float c_r = (mix(bgColor[0],fgColor[0], opacity));
float c_g = (mix(bgColor[1],fgColor[1], 1.0));
float c_b = (mix(bgColor[2],fgColor[2], 1.0));
gl_FragColor = mix(bgColor, vec4(c_r,c_g,c_b,1.0), opacity);
}else{ //downhill
float c_r = (mix(bgColor[0],fgColor[0], 1.0));
float c_g = (mix(bgColor[1],fgColor[1], 1.0));
float c_b = (mix(bgColor[2],fgColor[2], opacity));
gl_FragColor = mix(bgColor, vec4(c_r,c_g,c_b,1.0), opacity);
}
}
}
https://www.opengl.org/sdk/docs/man/html/fwidth.xhtml
https://www.opengl.org/sdk/docs/man/html/dFdx.xhtml
http://computergraphics.stackexchange.com/questions/61/what-is-fwidth-and-how-does-it-work
Ha ha ha :) ,
This version1 may not true subpixel rendering, But I think this look like what appears on my Windows7.
(left) msdf, (middle) v1 subpix rendering , (right) Windows Notepad