- 
                Notifications
    
You must be signed in to change notification settings  - Fork 21
 
msdf subpixel rendering v1
        win edited this page Oct 19, 2017 
        ·
        1 revision
      
    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