惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
博客园 - 司徒正美
WordPress大学
WordPress大学
爱范儿
爱范儿
小众软件
小众软件
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
罗磊的独立博客
博客园_首页
V
V2EX
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
The Cloudflare Blog
MyScale Blog
MyScale Blog
IT之家
IT之家
H
Help Net Security
Blog — PlanetScale
Blog — PlanetScale
Microsoft Security Blog
Microsoft Security Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recent Announcements
Recent Announcements
F
Fortinet All Blogs
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
人人都是产品经理
人人都是产品经理

Red Blob Games: latest blog posts

Red Blob Games: English: a vs an Red Blob Games: Differential heuristics Red Blob Games: Responsive design calculator Red Blob Games: Academic citations Red Blob Games: Highlighting interactive code blocks Red Blob Games: Optimizing page size Red Blob Games: Writing a guide to SDF fonts Red Blob Games: URLs with trailing punctuation Red Blob Games: What I did in 2025 Red Blob Games: Goodbye Sass Goodbye Sass Red Blob Games: RotMG map seeds Red Blob Games: Mapgen4 Mapgen4's use of WebGL2 Red Blob Games: Mapgen4 river shader Red Blob Games: Mapgen4 renderer Red Blob Games: Harnessing ChatGPT hallucinations Red Blob Games: Let Let's write a search engine, part 2 of 2 Red Blob Games: Let Let's write a search engine, part 1 of 2 Red Blob Games: Hexagon conversions Red Blob Games: Mapgen4 trade routes Red Blob Games: De-optimizing mapgen4 Red Blob Games: Hexagon spiral coordinates Red Blob Games: Thoughts on Flash Red Blob Games: What I did in 2024 Red Blob Games: Hexagon page animations Red Blob Games: SDF Halos SDF Halos
Red Blob Games: Signed Distance Field Fonts
2024-03-23 · via Red Blob Games: latest blog posts
Blog post: 23 Mar 2024

Each week I pick one or two things to work on. In week 2 of this year, I decided I should update my “hello world” OpenGL+Emscripten code[1] from 2015. It’s boilerplate I use occasionally in other projects. It wasn’t compiling anymore, and I wanted to fix that as well as several other things.

One of the unsolved issues in that starter code was that the fonts never looked good. I was using the stb_truetype[2] library, and got this output:

screenshot of stb-truetype rendering, with my old code

Look at how H and e are too far apart, and S and D are too close together. I tried various things but couldn’t figure it out, so I had two workarounds at the time:

  1. Use Omar Cornut’s Dear ImGui[3], which has nice looking font rendering.
  2. Use a monospace font to hide the spacing problems.

I decided to look into it again. After all, Dear ImGui uses stb_truetype, so why would my output be so different? After looking through the docs and also several examples, I concluded that my code was all wrong. I tried kerning but that wasn’t the issue. I tried a few different fonts but that wasn’t the issue. One issue on stb_truetype[4] suggests “left side bearing”. I found example code from Justin Meiners[5] that rendered nicely, and it was using left side bearing. But Dear ImGui doesn’t use it. And example code from Benjamin Attal[6] didn’t use it either. I spent many hours studying the docs and examples before I figured out how to rewrite my code[7]. It looks better now (although still not great — look at the gap between m and o):

screenshot of stb-truetype rendering, with my new code

This awakened my desire to play with font rendering. In particular, back in 2016 I bookmarked https://github.com/Chlumsky/msdfgen[8] with the note:

Multi-channel distance fields can represent sharp corners, unlike Valve’s original paper, which had rounded corners. This is C++ code to implement the algorithm described here: https://computergraphics.stackexchange.com/questions/306/sharp-corners-with-signed-distance-fields-fonts/2151#2151[9] (there’s also a thesis paper)

So I decided week 3’s project would be to try that out! It was a great week. I learned a lot.

screenshot of msdf rendering using msdfgen's library

Along the way I kept some notes about what commands I ran and what I learned. These notes were originally meant for myself only but I’m making them available because I think sometimes people don’t realize what my learning process is like. My articles especially present everything in the “final form” and readers might think I just write code like that from the start. I don’t! I have lots of bugs and dead ends and misconceptions along the way. I find that keeping a journal (for myself) helps me work through them.

Some high level notes:

  • Signed Distance Fields are cool.
  • There are some things I don’t understand about gamma correction, supersampling, outlines, antialiasing, etc. I experimented some but I feel like I still don’t understand these topics well.
  • Towards the end of the week there were several things I felt like I should have understood much earlier, but didn’t.
  • The code to generate the MSDF files may be complex, but the code to render is incredibly simple, probably under 50 lines.
  • I should take lots of screenshots and make lots of notes when I’m learning something.

Take a look my notes, as well as an interactive demo I used for testing my knowledge. Random tidbit: the 2403 in the url means year=2024 week=03. I’ve been using this naming scheme since 2015 for my weekly projects.

After playing with fonts week 2 and week 3, I still had more I wanted to do. But I am trying to keep to a project-per-week rhythm, so I decided to wrap up the basic font rendering and move on. In week 4 I’ll explore outlines and other effects. That’s the next blog post.