We’re making a competitive game, and we want to eliminate texture popping or streaming stutters during gameplay. We currently have texture streaming disabled completely, but from documentation, this seems to mean that all mip levels of textures will be loaded, even if they are not used. We still want to to drop mips based on the quality settings. What’s the best way to achieve this, short of rolling our own streaming system?
You are on the right track here- you definitely don’t want streaming completely disabled, as it serves a very important purpose. Without any form of streaming, there is nothing stopping your textures from completely eating into your VRAM, likely leading to GPU crashes the longer someone plays your game, or at the very least causing significant lagging.
There are a few different solutions you can take. The first, and probably easiest, is to use virtual texturing. In exchange for additional computational shader costs, your textures can be a lot more optimized by only needing to show the parts of the textures that currently need to be rendered. While you will still need to use mipping for this, you will find that you have a lot more wiggle room.
The other option is to optimize all of your textures, and if you have any that absolutely can’t be mipped, make sure you change their MipGen Settings to Effects or something similar to give them very low mip priority. Make sure textures are at the lowest resolution to still look the best (aka make sure they have good but optimized texel density). For me, this usually means BC and N textures at 2048 and my ORMs at 1024. This won’t prevent mipping entirely, but Unreal knows what to prioritize when mipping and optimized textures will prevent it from heavily mipping when it doesn’t need to. Also making sure that all textures (unless for a purpose) are power of two and are set to mip is very important. If you have any textures that can’t be mipped (a skybox being the only real answer here) then it’s super important that this texture is as optimized as possible, since it will always be eating into memory as long as its loaded.
Unfortunately, there is no one-click magic button. This is a process that involves purposeful optimization and testing. To see how your streaming pool is doing in-game/editor, you can use the console command “stat streaming”
This is a good video that goes over the texture pool and adjusting texture resolutions:
Thanks for your reply. We plan to be very careful with our texture budget. Our ideal solution is to load all needed textures at the highest mip required for the selected graphics settings when loading the level. We were hoping that disabling texture streaming will do that, but from our tests, disabling streaming will cause all mips to be loaded regardless of settings. Was hoping there is some combinations of comfiguration that can achieve this.
Hmm, well here are a few things that might help:
This setting in your texture will ensure that only the highest mip is loaded in instead of all mip levels.
If you want to directly control which mips your textures are using, you can do so here:
If you wanted to build up your own custom mipping system, you could do that through the use of setting this value via custom primitive data (per-object), material parameter collection (per group), or a quality switch (per-platform / per-scalability)