The texture streaming system, or streamer, is the part of the engine responsible for increasing and decreasing the resolution of each texture. This enables you to have good visual quality while
managing the available memory effectively. This is in part done with Mips, or Mipmaps, that are pre-calculated sequences of images for your texture resolutions. You can think of these like LODs for your textures.
For more information on Mips you can read about it on our Texture Support and Settings page.
The streamer has its own view of the world, and its update cycle consists of:
Updating the world view
Computing which resolution would be ideal for each texture
Choosing which resolution is actually possible based on the streaming pool size
Choosing which textures to update
Generating load / unload requests
To achieve those tasks, the streamer uses an async worker thread to reduce the workload on the game thread, so that only the first and last tasks above need to be done in the game update loop.
The world view consists of the list of all the textures used by each primitive component, and for each, world bounds and texel world sizes. From that information and a given viewpoint, it is possible to compute what
resolution would be required to get a good texel per pixel ratio. Additional information is then taken into consideration like whether this component was actually visible onscreen or not.
This ends up defining the ideal resolution for each texture. The streamer then computes if the streaming memory pool is big enough to hold those resolutions. If not, the streamer will reduce the planned quality for selected
textures, dropping one mip at a time, until the planned solution gets under budget.
The order in which textures are processed when dropping mips is defined by the retention priority, and follows these rules in order:
Keep landscape textures, forced load textures, and textures already missing resolutions
Keep mips that are visible on screen
Keep character textures and textures that don't take much memory
Drop mips that are not visible, dropping the last recently seen first
Once the streamer has determined what resolution it will load for each texture, it then computes which textures should be updated first according to the load order priority. The priority is defined by several criteria evaluated in order:
Load visible mips first
Load forced load textures, landscape textures, and character textures first
Load textures which are far from their target resolutions first
For those that are not visible, load the most recently seen first
The final step is to generate a batch of update requests, each of those either increasing or decreasing the current texture resolution. The amount of memory updated for a single batch is
limited by the temporary pool size, in order to keep the number of inflight requests low.