A few days ago, I gave a talk at the German Dev Days about reducing the size of textures in memory and on disk. Some parts of the presentation were based on my articles on Mip Flooding and Game Sizes, but I also researched topics that I hadn’t written about before.
After the talk, people asked me to upload the slides, but I don’t think they’re very useful on their own. Without a presenter, they’re rather cryptic. Also, due to time constraints, a lot of information didn’t make it into the slides. I’m now rearranging my notes and splitting them into several blog posts.
This is the first post in the series and focuses on UI textures.
Why Should You Care About UI Textures?
In my experience, when it comes to textures for 3D meshes, everyone is aware that VRAM is limited and that texture size matters. There are many well-known best practices for memory-efficient environment and character art, such as channel packing, tight UV layouts, trim sheets, and shared tiling textures.
However, when it comes to UI textures, the situation is very different. I have experienced multiple times that even experienced UI artists don’t have a good grasp of how UI textures can clog up memory or how to set them up to avoid that issue. There are reasons for this, but first, let’s look at why optimizing UI textures is worthwhile.
Streaming
Modern games are massive. Anyone who has had to download a game overnight before being able to play it knows what I’m talking about. In large open-world games with high-resolution environment textures, these textures can be several dozen gigabytes in size.
In comparison, UI textures may seem like a non-issue. In action games that have minimal UI, the combined size of all UI textures is negligible compared to the size of the other textures. You may think that a crosshair icon, an energy bar, and a few icons for the weapons and ammunition menu aren’t a big deal. But they are. Even though these textures may seem small at first, there’s a big difference between them and the other textures in your game:
These textures aren’t streamed. They remain in memory from the moment you start the game until you close it again. Compare that to environment textures. At any given time, only a fraction of them are loaded. Even then, they’re usually loaded at a low resolution, like 64×64 pixels. Only a few textures are loaded at full resolution.
Busy Work
It’s not uncommon for modern games to have thousands of textures. For tech artists trying to optimize the game, this makes manual optimization difficult, if not impossible. For small projects, it’s possible to go through the textures individually, remove duplicates, scale down large textures, and ask the artists to fix unoptimized UV layouts. On larger projects, however, that’s no longer an option. As mentioned above, the impact of removing a single environment texture is usually not noticeable.
Imagine a first-person shooter with 20 levels. While looking through the project folder, you find and remove a duplicate tree texture used at a specific corner of level 17. Even when profiling the memory usage in that level, there won’t be a difference as long as the player looks in the wrong direction while standing at that corner. Reducing your game’s memory usage by optimizing individual environment textures would require days, even weeks.
Now, compare that to optimizing UI textures. Suppose you find a way to reduce the crosshair size by 50%. The impact may not be significant, but it will be effective throughout your entire game.
That’s why, when you have a limited amount of time to optimize your game, UI textures are always worth your attention.
Predictability
UI textures are the most predictable type of texture in almost every game. As mentioned earlier, they are typically not streamed, so you always know how much memory they require once loaded. The number of loaded UI textures tends to be consistent and predictable for certain levels and situations. For example, to calculate the memory needed for the inventory, you can simply add the sizes of all the item icons. You know these textures will only be used in the inventory and nowhere else. This makes it easy to define budgets for UI textures.
Compare that to other textures and rendering resources, where the amount of memory used depends on the gameplay situation, camera perspective, screen resolution, aspect ratio, scalability settings, and streaming settings. UI textures are easy to get a hold off, so there’s really no excuse if they ever exceed their budget.
Why are UI Textures so Overlooked?
Nowadays, 3D artists don’t just paint pretty color textures. They must create a plethora of textures to control various physical properties. These include normals, ambient occlusion (AO), metallic, roughness, opacity, and specular, among others. To do so, artists must be knowledgeable about PBR theory and lighting. The same goes for meshes. Take a look at the export settings when exporting meshes from your 3D digital content creation (DCC) software. I don’t know of a single reputable 3D software program without a scroll bar in its export dialog. There are many topics that need to be addressed to create a complete 3D asset and import it into the engine.
In comparison, UI textures are deceptively simple. You paint a picture in Photoshop, and then it’s loaded and displayed in the game. That’s it. No technical knowledge is required. When exporting the image from Photoshop, you’re usually only asked whether you want to save your image with or without an alpha channel. UI art is often considered a topic that doesn’t require as much technical expertise as other types of art. Caring about size and other more technical aspects is an optional polishing step, not something people start with. As a result, many UI textures used in games aren’t optimized that well. On the plus side, this means that by mastering a few basics, you can make significant improvements.
What Can You Do About It?
Now that we know UI textures are something we should optimize, what are our options? The list below isn’t complete, but it contains several effective strategies.
Texture Compression
One thing I love about the Substance tools is that they can only be used to create textures with power-of-two resolutions. Any other resolution wouldn’t make sense because the tools are designed to create textures for 3D meshes, which require mip maps. To create these mip maps, you need textures with a power-of-two resolution. This is a perfect example of providing users with only the options they need.
UI textures are usually created in classic image editing software like Photoshop. This software isn’t specifically built for textures and doesn’t restrict its users. As a result, one might assume that UI textures can use any resolution. Sadly, that’s not the case.
To illustrate, here’s an example of a texture in two resolutions:

I didn’t change any settings for either texture. The only difference between them is their resolution. Interestingly, the one with the lower resolution is eight times bigger than the other one.
This is because basically every texture compression method works by splitting the texture into 4×4 pixel blocks. Each block uses a limited color palette so the texture needs less memory. I’m oversimplifying, but if you know enough about the topic to notice, you aren’t the target audience for this article anyway.

If a texture can’t be split into these blocks, the technique doesn’t work because there are leftover pixels that the compression can’t deal with. Because of this limitation, a texture’s resolution must be divisible by four. If this isn’t the case for both axes, the texture is stored uncompressed in memory.
As a general rule, every texture in your project needs to use a resolution divisible by four. Again, I’m oversimplifying. There are exceptions, but not for UI artists.
Old Advice
You may see people recommending the use of uncompressed textures for UI elements. That used to be solid advice, but I think that ship sailed quite some time ago.
Modern compression formats have improved significantly. Godot, Unreal, and Unity all offer BC7, which is nearly equivalent to uncompressed textures in quality. If BC1 were still your only alternative, I’d understand why uncompressed textures would be the better choice, but that’s not the case anymore.
Using no Textures at all
Games are unique in that they often use textures for UI. Other applications typically just use geometric shapes, outlines, subtle highlights, and drop shadows. Of course, games are supposed to look better than Microsoft Excel. However, that doesn’t mean you can’t use geometry and mathematics to design your UI. Even with simple shaders, you can design complex, sophisticated interfaces without using textures.
Unity has a nice sample of UI elements that use only shaders:

Unreal’s version of this is called the UI Material Lab.
I want to stress that using shaders to create your UI is not a compromise or an emergency solution. In many cases, shaders can provide considerably better quality than textures. Since the elements are created at runtime at the target resolution, they are always displayed sharply, regardless of resolution or scaling. There’s a reason that text in almost every application is displayed using vector graphics instead of textures.
The Full Screen Texture
From time to time, you may want to use a full-screen texture for a menu or loading screen. While full-screen textures aren’t always avoidable, they do come with their fair share of challenges.
Size
A properly compressed 4K texture with an alpha channel uses 8 MB of memory. That doesn’t seem like much at first. However, it adds up quickly. Imagine a loading screen that cycles through several pieces of artwork while you wait for the game to start. The loading screen system references ten textures to cycle through. Now, 80 MB of memory is used just for loading screens, which isn’t trivial anymore.
You could build a sophisticated loading screen system that loads only the next artwork while the current one is visible and unloads the previous one immediately after the switch. This reduces the memory usage to 16 MB.
However, when working in Unreal, for example, you can’t unload assets individually; you need to trigger garbage collection. Loading screens already take time, even without repeated garbage collections happening in the background. And even if you’d be okay with that, taking into account the effort to build and debug such a system, just reducing the size of the artwork is usually the preferable way to deal with this.
Before you say anything, yes, I’m aware that it’s 2025 and many people have 4K monitors. In general, I absolutely support creating UIs that can be displayed in native 4K resolution. However, this should only apply to smaller elements, not full-screen textures. High resolutions are most critical for moving content to avoid aliasing and for UI graphics that need to be sharp and precise. Scenic background images however can often be scaled down without a noticeable difference. Fortnite uses a resolution of 2048 x 1024 pixels for its backgrounds. Disco Elysium uses 1920×1080. When I worked on Park Beyond, I used a resolution of 2560×1440 for backgrounds. That’s a bit higher, but still much smaller than a proper 4K picture.
The Stupid Full Screen Texture
I won’t mention any names, but trust me when I say that it’s not uncommon to find textures like this, even in professional environments:

In this example, the tutorial required an arrow pointing to a specific UI element. Because tutorials are usually implemented late in the production process, when there is no time for anything else, monstrosities like this are the result. Everything about this texture is wrong:
- If the position of the UI element changes, someone must open the texture in Photoshop, move the arrow, and export the updated texture.
- If the UI changes dynamically based on UI scaling, for example, this approach falls completely flat.
- How does this approach work on screens with different aspect ratios? You could probably position the arrow so that it works for both 16:9 and 16:10 displays. But what about 4:3, 21:9, or 32:9?
- Most relevant to this article is the amount of unused empty space in this texture, which is downright criminal. This is especially problematic since the texture has an alpha channel, which doubles the size.
If you find yourself creating a full-screen texture that is mostly empty, a vignette, a gradient, or just a tint, reconsider. No matter how urgent the deadline, there are things that shouldn’t exist.
Aspect Ratios
It’s easy to forget that screens nowadays come in a variety of aspect ratios. Aside from the standard 16:9 and 16:10 ratios, an increasing number of screens have 21:9 and 32:9 ratios. These aspect ratios need to be considered early in the production process. The UI should be planned with them in mind. It’s easier to do this if you don’t use a static full-screen background image. Using individual elements that can be arranged in different ways makes you more flexible. Otherwise, you usually end up with ugly bars on the left and right, or you have to zoom in until the image becomes blurry.


Texture Permutations
Although the concept of permutations is better known in the context of shaders, it also applies to other assets, including UI textures. In this context, permutations are all the different variations of a single texture that result from changing the texture’s properties, creating different combinations. There are many reasons for permutations, and they can easily spiral out of control if not kept in check.
For example, consider building icons for a city builder. At first, it seems simple enough. Suppose there are 70 buildings in your game; you would need 70 icons. Then, someone decides that players need feedback when a building is selected, so you create versions of the textures with outlines. That doubles the number of icons needed, but that’s not too much of an issue. 140 textures are still manageable. Perhaps the game also has a research system, so you need a greyed-out version of each building. That’s a bit much, but not too dramatic.
However, you then reach a point where the number of permutations can spiral out of control. Maybe your game has different biomes, and you want a separate icon for each biome. To do that, though, you don’t need one icon per biome; now, you need three. With three biomes, that’s 490 icons in total. This is bad enough, but you’ve also painted yourself into a corner. If you ever want to add more versions of your buildings, adding even one version will require another 490 icons.

There are many reasons why permutations can happen, but when it comes to UI, there are a few classic causes:
- Localization: You’d think it was common knowledge to never use localized textures in games, but I’ve worked on two games that did. These textures contain readable text, so artists must create versions for all supported languages. Effort and permutations aside, localized textures are also problematic because, once created, they prevent writers from making text changes late in production. As long as the text exists only in a text file, the writers can make changes whenever they want. However, with localized textures, they now have to ask the art department to make the changes for them.
- Button states: You may think of the default, hovered, and pressed states. Have you considered selected (for the gamepad version), locked, and disabled?
- Dark/Light Mode: At least with this one, only one variation is needed.
- Platform-specific controller glyphs: Sony, Nintendo, and Microsoft have specific guidelines for how their controller glyphs should appear on the screen. Therefore, you need the correct versions for each platform.
- Tutorials, in particular, can cause issues. It’s common for tutorials to include screenshots or gameplay clips. However, as soon as they contain the actual localized UI, you have a problem. In the worst case, even controller glyphs are visible. If your game supports five different languages and is released on the three major consoles, that’s 15 permutations!
How to Avoid Texture Permutations
Some texture permutations are easier to avoid than others. The easiest ones to avoid are the classics, such as outlines, hovered states, and inactive states. Rather than using separate textures, shaders can produce the variations at runtime. In other cases, it’s best to change the design, such as replacing textures with localized text with pictograms. Generally, avoiding permutations isn’t difficult as long as you’re aware of the issue and make the appropriate decisions early on.
Channel Packing
When it comes to UI textures, channel packing isn’t as popular as it is for other textures. For UIs, there’s no need to store a lot of properties, so just a simple RGB image is enough.
If your UI uses a lot of greyscale masks, channel packing becomes an option, but I generally don’t recommend it if the textures stored in each channel aren’t related to each other and are not sampled together the same time.
Imagine you have 60 greyscale images of icons that are colored and displayed in the UI. You could use channel packing to store these icons in 20 RGB images, and save memory. But working with these packed images can quickly become a nightmare as you need to keep track which icon is in which channel of which texture, and then adjust shader parameters accordingly. While I’m usually for every optimization possible, it’s not worth it if you torpedo your workflow in the process.
Signed Distance Fields
Multi-channel signed distance fields (MSDFs) are a great way to store shapes and glyphs in very small textures with decent quality. Since distance fields are a big and complex topic, I won’t go into detail here. The above link leads to Viktor Chlumský’s MSDF generator. It’s an awesome, useful tool. If you are new to SDFs, I recommend reading the Valve paper that popularized the concept and trying out SDFs before attempting to work with MSDFs. They can already significantly reduce your texture sizes and are easier to understand, create, and use.

Good Enough
Congratulations! You’ve reached the end of the article. Now that you have an expansive toolbox for reducing the memory impact of your UI textures, you might be wondering: How critical is this topic really? Truth be told, it’s probably not that critical as long as you aren’t developing games for phones or retro consoles. Compared to the dense geometry, ray tracing acceleration structures, and other buffers modern games have to fit into memory, UI textures won’t be your biggest problem. Don’t focus too much on them, or you’ll be a prime example of the streetlight effect.
I still think UI textures are a worthwhile optimization target because they can be optimized easily, and artists can approach this topic without learning advanced graphics programming or understanding the advanced details of texture streaming heuristics. And having as many departments as possible involved in the optimization process is always a win in my book. Just make sure to get the easy gains first (ensuring texture compression, avoiding permutations,…) before you look into the advanced methods (SDFs, shaders).