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