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

推荐订阅源

云风的 BLOG
云风的 BLOG
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
博客园 - 三生石上(FineUI控件)
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
V
Visual Studio Blog
小众软件
小众软件
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
MongoDB | Blog
MongoDB | Blog
V
V2EX
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 【当耐特】
Microsoft Azure Blog
Microsoft Azure Blog
The Cloudflare Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Engineering at Meta
Engineering at Meta
L
LangChain Blog
Martin Fowler
Martin Fowler
GbyAI
GbyAI
博客园 - 司徒正美

Red Blob Games: latest blog posts

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 SDF Halos Red Blob Games: SDF headless tests, part 2 Red Blob Games: SDF headless tests, part 1
Red Blob Games: SDF Halos
2024-12-09 · via Red Blob Games: latest blog posts

I had previously posted about drawing outlines around fonts. The goal is to make labels easier to read in situations like these:

Small text on a map

Especially where the text and background are the same lightness, an outline with the inverse lightness can make it more readable:

Small outlined text on a map

These outlines are called “halos” in the cartography world. There are many styles[1] one can use. A solid outline is the simplest thing to implement, so I started with that. Apple Maps and Google Maps use a solid outline too. However, a solid color outline can be distracting[2], and Cartographer Tom Patterson instead uses background blurring with feathering (variable strength) to produce nicer looking halos[3]. That article made me want to try other styles.

With signed distance fields, the shader can map signed distance to a color. I made a visualization of this mapping. For plain text, everything below 0 is filled and everything above 0 is transparent:

Distance to color for plain text

I implemented outlines by setting the color at distances between 0.0 and 0.1:

Distance to color for outlined text

I also tried adding a separate soft outline (halo) that fades out over some distance:

Distance to color for soft outlines

Let’s look at little closer at the output:

Plain text rendering Text rendered with outline Text rendered with outline that fades
Three styles of text rendering: plain, hard outline, hard+soft outline

We don’t need outlines in regular UIs because the text is readable by default. Outlines are distracting. But in maps the variety of backgrounds means the safest thing is to use an outline. Let’s look at different areas of the output:

Areas to evaluate in rendered text

In area A the dark lines for the mountaintops make the text harder to read, especially at the bottom of the T and G. In the original image at the top of the page, the beginning of the word PEAKS is especially hard to read.

In area B the text is already readable without an outline. The same is true in area F. Area E is readable although it could be better.

In area C the black text is hard to read against a dark ocean background. Area D also has low contrast, especially the letter R.

What can we do to improve these? Regular hard outlines are the obvious answer. But I think area B looks better without the outline. And area B may be a common case in some map styles. So I wanted to try some other options for outline styles. Tom Patterson suggests blurring the background. I tried implementing an “outline” that uses the blurred background color:

Text rendered with a blur around it

I think this helps with area A. We can think of the label as being printed on frosted glass. The downside is that the map detail is lost. And it doesn’t help in areas C, D, E. Let’s combine this with hard and soft outlines:

Outlined text on blurred background

I still prefer area B without the outline. What would happen if I selectively applied the outlines? The shader can calculate the contrast at each pixel and suppress the halo over areas where contrast is good: B and F. Let’s see the halo only:

The halo rendering

Suppressing the halo in some areas gives us this (and it could be tuned up or down):

The halo rendering only when contrast is poor

Here’s the result:

Selectively outlined text on blurred background

However the downside of this style is that a label over different types of areas will look inconsistent.

Another thing I wanted to try is improving the outline in area C. It looks much stronger than the outline in area D. I tried tinting it the same color as the background:

Outlining text to match the background color

My experimental code only worked for the light outlines and not for dark outlines. I think I’ll have to revisit if I want to use it in a real project.

In terms of implementation, selective outlining, outline tint, and background blur all require me to read the background pixels from the map image. I converted my code to use linear rgb to make these calculations correct. Of these three features, background blur is the trickiest, because I’m also writing the blurred value out near the labels. If there are overlapping labels, what happens is that I draw the blurred background, draw the first label, draw the blurred background again, and draw the second label. This looks bad. It would be even worse if I didn’t combine distance fields as I described in a previous blog post. I didn’t try to fix any of this for these experiments. My goal was to see whether selective outlining, outline tint, and background blur help, not to make a production-quality text renderer.

I don’t know which of these techniques will look best in a real project, but I now have some options:

  1. Hard outline
  2. Soft outline (halo)
  3. Blurred background
  4. Selective outline
  5. Tinted outline

Applying all of them to the example from the top of the page, I think it’s an improvement over the regular hard outlining:

Text with outlines Text with hard and soft tinted selective outlines with blurred background
Before and after comparison

In games like Magic The Gathering you spend some of your time collecting cards for your deck and some of your time playing those cards in a game. These font experiments for me are the “deck building”. I’m learning a lot, and I now have more options available. But at some point I want to use this in a real project.