How do I optimize textures for my 3D assets?

I’m currently finishing some assets for UE4. As an artist, how do I go about optimizing my textures? Is it just enough to include a variety of resolution maps (ex. 4k,2k, 512). I have thought about materials IDs. How much do they affect the performance?

I can give you view from programmer perspective

Textures by themselves don’t take performance as once texture lands to VRAM it just sits there and all depends on how it samples and process by the shader… but thats shader job. So textures mainly effect VRAM usage, the more VRAM used the more UE4 gonna swap data on it and risk of running out of memory and crash increases. Shaders also have texture sampler limit. GPU don’t recognize types of maps, for them they are just textures like any other and shaders which GPU executes give them proper function.

Textures are also laoded to VRAM as either raw bitmap or lossless compression format (like DXT) as GPU don’t understand compressed images like PNG or JPG, so they take more space on VRAM then there file counterpart

You can decrese number of maps by putting single channel once (white and black maps) to single texture on different color chanell and on shader separate them route them. Shaders are super fast and just sampling and routing color channels should be breeze even for low spec GPU, even simple calculations are fine, problems is if you do some heavy calculations or resampling.

There are two basic guiding principles when it comes to textures:

  • Use as few of them as possible: Try to combine different surfaces into a single texture (google “texture atlas”) so the video card doesn’t have to juggle with too many of them at once.
  • Use as much of a texture as possible: Don’t waste texels. It’s a bit trickier if you are baking textures because there the UV layout makes or breaks a good texture: If the UV islands are too far from each other then the gap between them is wasted; if they are too close then in higher MIPs they can bleed onto each other, producing seams.

Speaking of MIP mapping, you don’t have to worry about manually creating different resolutions for textures, the engine will take care of that. Just create the source image in as high res as you can, you’ll be able to set the in-game size later.

Anyway, there is more to texture optimization that this (packing, tiling, mixing different frequency details, procedurally changing parts of a texture to avoid storing slight variations of the same texture, etc) but those are longer topics.

I hope this helps, let me know if you have questions. :slight_smile:

Thank you for your response, it is really helpful. Well, im having a scenario where i’m building a massive city with enterable buildings. I’m just having an idea about optimizing my material ids. Without any optimization, my city would have over 10k materials, but with some management, I can cut that number in half without losing too much detail. My city is pretty low poly and it is possible that it will be used on mobile platforms also. Do they handle the # of material IDs the same? If the device has enough VRAM it won’t make a difference to them? If I use less material IDs, what are the benefits, except less VRAM usage? Will I get less draw calls?

Thank you for your answer it was really helpful. I already posted this comment, i’m pasting it here if you can answer it

Well, im having a scenario where i’m building a massive city with enterable buildings. I’m just having an idea about optimizing my material ids. Without any optimization, my city would have over 10k materials, but with some management, I can cut that number in half without losing too much detail. My city is pretty low poly and it is possible that it will be used on mobile platforms also. Do they handle the # of material IDs the same? If the device has enough VRAM it won’t make a difference to them? If I use less material IDs, what are the benefits, except less VRAM usage? Will I get less draw calls?

That seems like a really big undertaking with many places where you can (and will) run into issues. Performance optimization is a deep rabbit hole but here is the link to an article from Bob Cober which should get you started:

Sorry, my example was extreme. My buildings on LOD0 have 2-3 materials max, and on LOD1 they have 1. So 5 buildings on LOD0 and 30 buildings on LOD1 would be about ~50 material IDs, which I think is okay. Thank you for the article, it’s probably the best one I’ve read so far. If my city has 100 buildings, and only 20 are unique, what would be the best approach to optimize it? Is there a way to share those 20 unique textures among 100 meshes? Or is that something that programmers will do, since I will be creating an asset that will be used by different teams on different projects?

A lot depends on the target platform and the actual contents of the game but using Hierarchical Level of Detail (Hierarchical Level of Detail Overview | Unreal Engine Documentation) and instanced static meshes will help a great deal.

Thank you, instanced static meshes was the answer. But if i supply my assets as single buildings, is it the game developers job to do the instancing? (i want to put a building pack on asset store).

Yes, the level designers and technical artists should take care of optimizing the levels, if you just provide the assets then you don’t have to worry about it. If you optimized the asset (minimizing drawcalls, polycount, providing colliders, etc) then you are good to go.