Introducing Texture Streaming


3/23/26 Update


Hello Creators,

We are excited to announce that Texture Streaming is rolling out to clients across platforms starting today. Texture streaming gives you the freedom to add more texture variety and detail to your experiences without having to worry about scaling across all devices. It does this by rapidly loading baseline quality textures first in order of importance and then increases quality of textures up to the available memory on the device.

With texture streaming,

  1. Perceived load times can be much faster and total download sizes can be lower
  2. Important objects in your scene get higher quality textures without sacrificing stability
  3. Your players will face fewer Out of Memory (OOM) crashes due to textures

As a creator, you don’t have to do anything to enable texture streaming within your experience. As it rolls out on each platform, your players will automatically get the above benefits. We will keep this post updated with the latest roll-out status so make sure you like / follow this post to follow along.


Let’s dive into each of these improvements in more detail using the Modern City Template as an example.

Faster perceived load times and lower download sizes

With texture streaming, textures rapidly load in at a baseline quality first and in order of importance – so your players perceive your experience almost instantaneously. After the initial load, texture quality is progressively ramped up to the highest quality each device can support based on scene importance. Object importance is determined by a number of factors including distance from the camera and how much screen-space the texture takes up.


Side by side comparison of loading textures from a clean cache with and without Texture Streaming enabled. Timers stop when all textures in the scene have loaded at baseline quality.
Both videos were captured with a 100Mbit/s network connection

Using the new cloud transcoding infrastructure, textures are transcoded into individual Mippacks allowing the engine to request and load texture Mip packs with a lot more granularity. Everything the engine does download is compressed in flight and at rest when stored in the local disk cache, further reducing download sizes.

Modern City Template Without Texture Streaming With texture Streaming
Time to baseline quality (Initial load) 20.6s 3.0s
Time to steady state quality 20.6s 9.9s
Texture memory used 280 MB 155 MB
Total download size (all assets) 236 MB 110 MB

Table comparing key stats without and with texture streaming enabled on the Modern City Template experience. These numbers were captured from the same scene above on a single run with a 100Mbit/s network connection.
Note: Actual numbers experienced by players in your experience will vary based on scene complexity, other scripts you might have and several other factors.

Texture quality distribution based on scene importance and a strict budget

With texture streaming, the engine continuously evaluates the resolution at which each texture should be rendered, based on the importance of the object it is mapped to (e.g., screen footprint). This allows the engine to allocate memory budget to the right textures and avoid wasting memory on unnecessary ones, while staying within the budget set by Harmony. As a result, players see high-quality textures where they matter most, and the engine can reclaim texture memory where they don’t.


Side by side debug view showing how texture resolution is selected based on scene importance on the right (With Texture Streaming) whereas all textures are simply loaded at the highest quality on the left (Without Texture Streaming). The Colors in the debug view represent desired ideal texture quality. Red = highest quality, Yellow = medium and Blue / Cyan = lowest quality.


Another side by side comparison of the same scene without and with texture streaming enabled on a low-end Android device. Notice how with texture streaming enabled, you get higher quality textures on the road and the avatar since they are deemed more important while the entire system still stays within a reasonable texture memory budget

Fewer out of memory (OOM) crashes

As Harmony can dynamically set the total texture budget based on available resources and the texture streaming system has multiple levers to stick to the budget, this can drastically reduce the probability of an out of memory event occurring due to texture memory. One of the leading causes of OOM crashes on low-end devices is due to the resource spike caused by loading a large number of textures when an experience first loads. With texture streaming, these spikes are smoothed out over time allowing your players to stay in your game no matter how much texture detail you throw at the engine.


:red_circle: Red: Texture memory required (MB) without texture streaming enabled
:green_circle: Green: Texture memory required (MB) for Ideal quality textures with texture streaming enabled
:white_circle: White: Texture memory required (MB) for Baseline quality textures with texture streaming enabled
:black_circle: Grey: Actual texture memory used by the system (MB) with texture streaming enabled

As we enter Modern City Template, we can see the legacy system shooting up to 225MB and staying there. With texture streaming, we only go up to ~50MB to reach ideal quality from the initial spawning point.

As the player moves around (~frame 850), additional mips for approaching objects are loaded (the grey line increases), but the amount of memory actually required to stay at ideal quality barely moves (green line) because we need less detail on the objects we’ve moving away from.

If a low-memory event occurs, the system can safely drop back down to the green line with no quality loss. The engine can always re-load these mips into memory later if necessary. In the worst case, if Harmony needs to reclaim even more texture memory budget to prevent a crash, the system can drop all the way down to the grey line – trading off texture quality momentarily to keep the player in the experience. As soon as memory frees up, the system can ramp up quality again.

What does Texture Streaming work with?

With this first release of texture streaming, we are enabling the system on the most frequently used instances that utilize textures to get the largest impact. Here is a quick summary on the specific instances that texture streaming will work with today:

Best Practices

While texture streaming was designed to work out of the box with your existing experiences, there are some best practices you can follow to get the most out of the system:

  1. As you build confidence in the system once it is released on all platforms, you should feel liberated to use more unique textures in your experience.

  2. Only use texture atlases if they are typically seen together on parts that are batchable (such as block parts, the same mesh, etc.) If one texture in an atlas is required at a certain mip level, the entire atlas will be streamed in at that mip level whether the remaining textures are being sampled or not. Texture streaming will work better with individual, unique textures, if they are not batchable.

  3. Use near-uniform texel density in your UV-mapped meshes. This will allow the mip selection heuristic to produce the best results.

  4. Be aware of the instance types currently supported by texture streaming. If an instance is not supported yet (e.g.: ParticleEmitter), you will still need to be judicious about texture memory until it is supported by texture streaming

How it all works: The lifecycle of a texture

Expand this section for a more nerdy and detailed look at how the end to end pipeline works

The end to end texture pipeline today consists of several steps, many of which have been overhauled to support texture streaming

Cloud:

  • Upload + Ingestion: You upload an image to Roblox In Studio or via OpenCloud Asset APIs

  • Storage: We store your original image at up to 8k resolution

  • Processing: Our cloud transcoders generate multiple platform-specific representations and resolutions of your image (various “mip levels”) and then compresses and packs them into a series of Mippacks ready for download.

Client:

  • Harmony: Harmony is continuously monitoring the available memory resources on the device. Every frame, it sets a total texture budget for the texture streaming system balancing the needs of all subsystems within the engine.

  • Texture streaming: The texture streaming system continuously evaluates all instances it needs to draw in a given frame and conservatively estimates what mip resolution the GPU will use, so that it can have all necessary mips available in memory.

    1. During the first few frames, when your experience is starting up, the system biases toward retrieving a minimally acceptable mip resolution on all instances first. This ensures the world around the player is perceptible as quickly as possible.
    2. Then, it will try to load mips up to the ideal resolution for all textures
      • If there isn’t sufficient memory budget from Harmony, it will first trim mip levels above the ideal resolution on less important objects.
      • If there is still insufficient budget, it will continue trimming mips below the ideal resolution.
    3. This evaluation of quality vs. importance vs. residency happens continuously as the player moves through the experience requiring the engine to load more and more textures.

    With texture streaming, the same scene at the same quality—or better quality—will use less or equal memory compared to rendering without texture streaming.

  • Texture fetching: The texture streaming system loads the required texture mips from the CDN or from the local disk cache. For efficiency, when fetching from the CDN, multiple mips are batched together into a “Mippack” for the lower resolutions. The priority of pending requests is continually adjusted to adapt to sudden changes in the game—such as teleports, newly spawned objects, etc.—so that older, less important requests do not delay newer, higher-priority ones.

What’s next

Texture streaming is a major step towards our goal of giving you freedom to create without having to worry about scaling your experiences across devices. Alongside other technologies like SLIM and Instance streaming, we hope to see a whole new era of experiences that push the boundaries of visual fidelity on Roblox.

With this foundation, here is where we are planning to go next:

  1. Address your feedback: Make further improvements to the system using feedback from you and from our own internal tests.**
  2. Enable 4k Texture rendering: With texture streaming in place, we feel confident that we can safely enable 4k texture rendering on the platform, for the instance types that support texture streaming, now that the engine can dynamically scale texture quality up and down. Give it a try in the 4k texture rendering Studio Beta.
  3. Enable texture streaming across more instances: As mentioned above, we focused this initial launch on the most frequently used instances to have the most impact. We hope to tackle UI textures and other instances over the coming months so all instances can stream in textures in a coordinated manner.
  4. Enable mesh streaming: Other than textures, meshes are the most used asset type on Roblox so we plan to bring the same improvements to meshes as well. Since textures are requested only after downloading the mesh, we expect to see further improvements to perceived load times, OOM crashes and even SLIM once we can interleave both mesh and texture asset streaming together. Mesh streaming will be released alongside a vastly improved Mesh LoD simplification algorithm as we announced at RDC.

We really value your feedback and any bug reports. As you test out these new improvements in your experiences, feel free to post before / after results below (especially if you notice something amiss)

Thank you on behalf of the Rendering, Geometry and Content platform teams.

279 Likes

Very excited for 4k textures and mesh streaming to follow :smile:

One slight concern. Does this penalize some aspects of performance at all. What if u have a lower VRAM GPU with more aggressive streaming. What kind of things will unload textures?

Separately I appreciate the nerd talk, I find this very cool, keep that up!

22 Likes

Nice! This will go well with SLIM, excited to use both of these great features. My phone barely runs Roblox, so I’ll see if it runs better in a few weeks because of this.

4 Likes

what about resample mode on textures? but this is a w update too

5 Likes

This is slightly unrelated, but I was wondering how extensively the engine uses local disk caches for asset data. You mention that texture mips can be retrieved from the on-device cache, but I was wondering if this is common-place, and if this can also be extended to meshes and other assets. It would be really nice if place/asset loading times can be further reduced in the case of in-universe teleports, like when teleporting the player from a main lobby to a match. Such a scheme currently results in the place having to be re-streamed, which is a point of friction for fast gameplay loops.

2 Likes

They’ll just hit you with the “but we gotta support legacy avatars!!” garbage and nonsense excuse for that one.

3 Likes

Yes, various disk caching happens of assets and other content. See the %temp%\Roblox directory on Windows for example.

4 Likes

Does texture streaming apply to any textures? e.g. Decals, SurfaceAppearance, Materials? Our game heavily relies on textures/mesh so this paves the way forward for even more detailed experiences for us.


24 Likes

Yes, this applies for MeshParts, SurfaceAppearance, MaterialVariant, Decal, Sky.

4 Likes

Aren’t legacy avatars barely supported in the first place? I’m surprised Roblox hasn’t already tried to give R6 the axe at this rate considering how nearly every avatar feature implemented since then is exclusive to R15.

3 Likes

image
:smiling_face_with_tear:

10 Likes

Finally, thank you. I’ve been always implementing home made solutions to this for the last 5 years. Appreciate this being done especially for a variety of instances :folded_hands:

That’d do infinitely more harm than good, lol

4 Likes

You’d think that’d stop them from doing it?

Considering more recent events, I’d totally expect nuclear changes to the platform like this.

1 Like

Wow what a treat! I knew 4K textures and other goodies are coming but this was a surprise. This will be a major benefit to Jailbreak, we use textures for everything from buildings to cars to roads. It’s a lot to load in.

17 Likes

Is this enabled, can I go on a game I crashed with my mobile device to test this? Are any Graphic Levels impacted?

can this allow for a feature of PBR texture projection (or some sort of texture painting feature)? i’ve seen some talks about it, but it’s mainly been referred to dynamic one. i’m asking for decal projection thats baked into the texture

Hence why I said “garbage and nonsense excuse”. They shot down ResampleMode on Materials & Textures/Decals for the excuse that they “couldn’t find a way to make it work on legacy avatars” which is garbage because there’s precedent for other modern features like PBR being disabled on legacy avatars.

5 Likes

So does this mean that, along with texture streaming for Terrain, the terrain optimizations / improvements showcased at RDC a couple of years ago, like better memory usage, smoother terrain, and customizable grass textures, are finally on the way?

7 Likes

Well, classic clothing isn’t even that big in resolution, so is just useless to add.

3 Likes