Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rendering beautiful text using MSDFs and Metal

Avatar for Kapsy Kapsy
April 10, 2025
36

Rendering beautiful text using MSDFs and Metal

Slides for my talk given at try! Swift Tokyo in April 2025. For the original keynote presentation, containing video, please go here: https://www.icloud.com/keynote/023sg8naQpfLzL5UYhThho3zQ#kapsy%5Ftry%5Fswift%5F2025%5Ffinal

Avatar for Kapsy

Kapsy

April 10, 2025
Tweet

Transcript

  1. • ZOZO, Inc measurement since 2017 • Graphics and audio

    programming • Founder kapsy.io • Building variations.app (real time, programmable generative music) • x.com/kapsy1312 • m.youtube.com/@kapsy1312 • github.com/kapsy • speakerdeck.com/kapsy1312 Mike aka Kapsy
  2. func MakeCameraTransform(portal: Rect, cam_portal_offset: V2, cam_pos_world: V2, zoom: V2) ->

    M3 { let Pm = portal.min let Pd = Dim(portal) let Pd_offset = Pd*cam_portal_offset let Pc = Pm + Pd_offset let Z = zoom let Cw = cam_pos_world let c = Pc - Z*Cw let res = M3(V3(Z.x, 0.0, 0.0), V3(0.0, Z.y, 0.0), V3(c.x, c.y, 1.0)) return res }
  3. Chlumsky, Viktor. Shape Decomposition for Multi-channel Distance Fields. Master’s thesis.

    Czech Technical University in Prague, Faculty of Information Technology, 2015.
  4. Chlumsky, Viktor. Shape Decomposition for Multi-channel Distance Fields. Master’s thesis.

    Czech Technical University in Prague, Faculty of Information Technology, 2015.
  5. Chlumsky, Viktor. Shape Decomposition for Multi-channel Distance Fields. Master’s thesis.

    Czech Technical University in Prague, Faculty of Information Technology, 2015.
  6. fragment float4 FragmentShader(Vertex2Frag in [[stage_in]], array<texture2d<float>, count> textures [[texture(0)]]) {

    float4 out; texture2d<float> texture = textures[texture_idx]; constexpr sampler texture_sampler(address::clamp_to_edge, filter::linear, mag_filter::linear, min_filter::linear, compare_func::less); out = float4(texture.sample(texture_sampler, in.uv)); return out; }
  7. Chlumsky, Viktor. Shape Decomposition for Multi-channel Distance Fields. Master’s thesis.

    Czech Technical University in Prague, Faculty of Information Technology, 2015.
  8. Chlumsky, Viktor. Shape Decomposition for Multi-channel Distance Fields. Master’s thesis.

    Czech Technical University in Prague, Faculty of Information Technology, 2015.
  9. fragment float4 FragmentShaderSDF(Vertex2Frag in [[stage_in]], array<texture2d<float>, count> textures [[texture(0)]]) {

    float4 out; texture2d<float> texture = textures[texture_idx]; constexpr sampler texture_sampler(address::clamp_to_edge, filter::linear, mag_filter::linear, min_filter::linear, compare_func::less); out=float4(1,1,1,1); out*=in.color; float sd = float(texture.sample(texture_sampler, in.uv)); float screen_px_range = 0.5; float screen_px_dist = screen_px_range*(sd - 0.5); float opacity = clamp(screen_px_dist + 0.5, 0.0, 1.0); out.a *= opacity; return out; }
  10. Chlumsky, Viktor. Shape Decomposition for Multi-channel Distance Fields. Master’s thesis.

    Czech Technical University in Prague, Faculty of Information Technology, 2015.
  11. Chlumsky, Viktor. Shape Decomposition for Multi-channel Distance Fields. Master’s thesis.

    Czech Technical University in Prague, Faculty of Information Technology, 2015.
  12. Chlumsky, Viktor. Shape Decomposition for Multi-channel Distance Fields. Master’s thesis.

    Czech Technical University in Prague, Faculty of Information Technology, 2015.
  13. Chlumsky, Viktor. Shape Decomposition for Multi-channel Distance Fields. Master’s thesis.

    Czech Technical University in Prague, Faculty of Information Technology, 2015.
  14. fragment float4 FragmentShaderMSDF(Vertex2Frag in [[stage_in]], array<texture2d<float>, count> textures [[texture(0)]]) {

    float4 out; texture2d<float> texture = textures[texture_idx]; constexpr sampler texture_sampler(address::clamp_to_edge, filter::linear, mag_filter::linear, min_filter::linear, compare_func::less); out=float4(1,1,1,1); out*=in.color; float4 msd = float4(texture.sample(texture_sampler, in.uv)); float sd = max(min(msd.r, msd.g), min(max(msd.r, msd.g), msd.b)); float screen_px_range = 0.5; float screen_px_dist = screen_px_range*(sd - 0.5); float opacity = clamp(screen_px_dist + 0.5, 0.0, 1.0); out.a *= opacity; return out; }
  15. References Shape Decomposition for Multi-channel Distance Fields Chlumsky, Viktor. Master’s

    thesis. Czech Technical University in Prague, Faculty of Information Technology, 2015. Improved Alpha-Tested Magnification for Vector Textures and Special Effects Chris Green, Valve 2007 Legendary Font Rendering https://www.youtube.com/watch?v=_t3mtjoHuoQ Tsoding, 2023 Handmade Hero Chat 016 - Drawing a Circle on a 286 https://www.youtube.com/watch?v=kVtDEy1ndYg Casey Muratori, 2019