msdf.glsl (2392B)
1 struct VSOut { 2 vec4 colour; 3 vec2 uv; 4 }; 5 6 #ifdef VERTEX_SHADER 7 8 in vec3 position; 9 in vec4 colour; 10 in vec2 tex_coord0; 11 12 out VSOut v2f; 13 14 void main() { 15 gl_Position = vec4( position, 1.0 ); 16 v2f.colour = colour; 17 v2f.uv = tex_coord0; 18 } 19 20 #else 21 22 in VSOut v2f; 23 24 uniform sampler2D atlas; 25 26 out vec4 screen_colour; 27 28 float median( vec3 v ) { 29 return max( min( v.x, v.y ), min( max( v.x, v.y ), v.z ) ); 30 } 31 32 float sample_msdf( vec2 uv ) { 33 vec2 msdfUnit = 2.0 / vec2( textureSize( atlas, 0 ) ); 34 vec3 sample = texture( atlas, uv ).rgb; 35 float sigDist = median(sample) - 0.5; 36 sigDist *= dot( msdfUnit, 0.5 / fwidth( uv ) ); 37 return clamp( sigDist + 0.5, 0.0, 1.0 ); 38 39 /* sigDist *= ( 2.0 / atlas.w ) * ( 0.5 / fwidth( uv.x ) ) */ 40 /* + ( 2.0 / atlas.h ) * ( 0.5 / fwidth( uv.y ) ) */ 41 } 42 43 float linearstep( float lo, float hi, float x ) { 44 return ( clamp( x, lo, hi ) - lo ) / ( hi - lo ); 45 } 46 47 vec4 sample_msdf( vec2 uv, float half_pixel_size, bool border ) { 48 vec3 sample = texture( atlas, uv ).rgb; 49 float d = 2.0 * median( sample ) - 1.0; // rescale to [-1,1], positive being inside 50 51 vec4 border_colour = vec4( 0.3, 0.3, 0.3, 1.0 ); 52 vec4 text_colour = vec4( 0.0, 0.0, 0.0, 1.0 ); 53 54 float alpha = step( -d, 0.0 ); 55 return vec4( vec3( 1.0, 0.0, 0.0 ), text_colour.a * alpha ); 56 57 // if( border ) { 58 // float border_amount = linearstep( -half_pixel_size, half_pixel_size, d ); 59 // vec4 colour = mix( border_colour, text_colour, border_amount ); 60 // 61 // float alpha = linearstep( -3.0 * half_pixel_size, -half_pixel_size, d ); 62 // return vec4( colour.rgb, colour.a * alpha ); 63 // } 64 // 65 // float alpha = linearstep( -half_pixel_size, half_pixel_size, d ); 66 // return vec4( text_colour.rgb, text_colour.a * alpha ); 67 } 68 69 void main() { 70 bool border = true; 71 72 vec2 fw = fwidth( v2f.uv ); 73 float half_pixel_size = 0.5 * ( 1.0 / 14.0 ) * dot( fw, textureSize( atlas, 0 ) ); 74 75 screen_colour = sample_msdf( v2f.uv, half_pixel_size, border ); 76 screen_colour += 0.5 * sample_msdf( v2f.uv - vec2( 0.354 * fw.x, 0.0 ), half_pixel_size, border ); 77 screen_colour += 0.5 * sample_msdf( v2f.uv + vec2( 0.354 * fw.x, 0.0 ), half_pixel_size, border ); 78 screen_colour += 0.5 * sample_msdf( v2f.uv - vec2( 0.0, 0.354 * fw.y ), half_pixel_size, border ); 79 screen_colour += 0.5 * sample_msdf( v2f.uv + vec2( 0.0, 0.354 * fw.y ), half_pixel_size, border ); 80 81 screen_colour *= 1.0 / 3.0; 82 } 83 84 #endif