White Shining Rock Logo
White Shining Rock Logo

UI Redo: Part 4 - Scaling

November 5, 2021 | Dukus | 12 Comments

Back when I made console games, there was a fixed resolution and all user interface assets were made for that resolution. It was awesome and easy. PC games, not so. Even console games now are tricky if you ship multi-platform and have a huge resolution range. I wanted to take care of this.

My next game might be displayed on something with a low resolution of 1280x720. Or a super high resolution 3840x2160. In my office I'm developing at 2560x1440. My old TV in my office that I test on is 1920x1080. I need to support all of them. And if one day, people are still playing and the resolution is 7680x4320, it'd be nice if it just works.

My previous UI was pixel perfect (meaning what I developed to be displayed was displayed exactly like that, per pixel, no scaling). And because it was pixel perfect at UHD resolutions, the UI was too small. If it was scaled up, everything was just stretched. I doesn't look great when scaled up 3x. But I didn't realize the need for a better solution at the time.

Here's an example of some text, and what it looks scaled up 3x.

Pretty fuzzy.

My solution currently is to use signed distance fields (SDF) and multichannel fields (MSDF) to store UI elements. This allows fonts and elements to scale up and maintain a crisp edge. Using it changes the way the data is stored, but not the amount of data I had. So that's nice and the results are decent.

This changes the font data stored to something crazy looking like this (as compared to the loading images shown in the previous post).

Using some math in the pixel shaders it results in much crisper edges when scaled up, and looks fine at 1:1 resolution.

There are some issues with tiny pixel or sub pixel sized elements with SDF scaling (like small fonts), but with TV distance readable elements, it has not yet been an issue for me.

Some games use SDF to allow huge scaling of fonts and crisp fonts in 3D, but that's not my goal here. My goal is to display the same UI at two different resolutions. If there's a 32 inch 720p screen, and a 32 inch 2160p screen, the user interface elements should both be the same size, and look as good as possible.

Here's an example. On a smaller screen, these buttons would be rendered at around 60 pixels tall.

In the old code, if scaled up to work on a screen with a higher resolution this would be the blurry result.

But with the new method, crisp lines are maintained. There's a few differences here compared to what I'd get if rendering native vector graphics, but as these elements would actually be the same width measured with a ruler, so you probably wouldn't notice.

I'm also supporting SVG (vector images) as inputs into my user interface. (These make it a little easier to generate an SDF.) While the SVG files are currently rasterized or turned into SDF, if I ever need to change sizes of things, it's easy. I can also then switch to a direct vector rasterizer if I ever choose to do so or decide that using distance fields isn't working well enough.

Leave a Reply

Your email address will not be published.

12 comments on “UI Redo: Part 4 - Scaling”

  1. Reminds me when I was in the business of corporate website creation, I first started designing for pixel perfect layouts. Then larger res monitors came into play and I had to start designing in percentages of screen real estates instead of pixel precise.

  2. Awesome. I would love to help test this when your ready. I haven't played video games in two years. I went right back to banished.

  3. This is really cool - There is a feel to some of the UI components in Banished, including the logo and load screens that at first sight felt clean and aesthetically pleasing in a way that it set expectations for the entire game, (expectations that the game actually met). I now know the technique and why it felt different than other games. Your attention to detail shows and it’s part of why I love your games.

  4. Speaking of console. I do hope yuour next game is on multiple platforms. As much as i adore banished on pc I could definitely get behind sitting on the couch with the xbox playing on a tv for a few hours.

  5. I'm still a caveman who generates bitmap fonts at runtime using FreeType, and re-generating them when the user changes the screen resolution. Nice to see there's an affordable solution to avoid that, and that also avoids requiring several bitmaps for the same font at different sizes 🙂

  6. Does that mean that the UI can be upscaled more in the next update? Because whenever I play on 3840x2160, all the UI becomes so small that it is basically unreadable, even when I upscale UI to the max...

  7. Just wondering Why not use vectors to render the text and ui buttons. thats just my thought I dont know much about game design so hence why im asking?

  8. Only recently discovered banished. I am a late comer to programming but going to get into unity in 2022. Your blog is quite Interesting. Keep up the good work.

More Posts

Code Rot

April 17, 2022

UI Redo: Part 3

October 25, 2021
1 2 3 47
Back to devlog
Back to devlog
© Copyright 2021 Shining Rock Software
Website Design & Branding by Carrboro Creative
menu-circlecross-circle linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram