Texture Streaming, Texture Quality and Performance

Texture Streaming was introduced for the Vulkan API in update 0.37. It lets the engine load texture mip levels on demand instead of keeping every texture at full resolution in memory.

Since update 0.39, Direct3D 12 is also supported and includes texture streaming support.

Texture Streaming is supported only on:

  • Vulkan
  • Direct3D 12

It is not supported on Direct3D 11.

What texture streaming does

Texture streaming loads texture detail on demand. Instead of keeping every texture at full resolution in VRAM, the renderer tracks which mip levels are needed and requests higher or lower resolution mips as required.

BeamNG uses GPU feedback to determine which mip levels are sampled during rendering. The streaming system prioritizes textures that are visible and close to the camera, while keeping distant or unused textures at lower resolution.

This reduces:

  • Lower VRAM usage
  • Better stability on memory-limited GPUs
  • Reduced loading pressure in large scenes
  • More efficient use of texture memory
  • Better scalability across different hardware

Streamable textures may initially load at a lower mip level. Higher-resolution mips are streamed in later when needed.

VRAM budgeting

Texture streaming uses a VRAM budget to decide when to load or unload high-resolution mip levels.

  • When VRAM usage is below roughly 50%, the engine can keep more high-resolution mips resident, reducing visible texture pop-in.
  • When VRAM usage rises above roughly 50%, the engine may begin unloading unused high-resolution mips.
  • When VRAM usage approaches roughly 90%, the engine normally stops loading additional high-resolution mips to avoid running out of VRAM.

There is an exception for GPUs with memory budget below 6 GB. On these systems, the engine may continue allowing higher-resolution mips to stream in even near the normal stop threshold, so textures do not stay permanently too blurry on lower-memory hardware.

If the streaming budget is reached, textures may appear blurry or muddy because higher-resolution mip levels are not being loaded. This is intentional: it is better for the game to remain playable than to run out of VRAM.

The budget is based on the GPU memory budget reported by the graphics driver, not always the exact advertised VRAM size of the GPU.

Storage speed

Texture streaming depends on how quickly texture data can be read from disk.

A slow HDD or SSD can increase the time it takes for high-resolution mip levels to appear. This may cause visible texture pop-in, where textures start blurry and become sharper after a delay.

Fast SSDs improve streaming responsiveness, especially in large levels, with many vehicles, or when moving quickly through the world.

Texture Quality setting

Texture Quality controls the maximum texture resolution used by the renderer.

Texture Quality Resolution impact Example from 4096x4096
Normal Full resolution 4096x4096
Low Drops by 1 mip level 2048x2048
Lowest Drops by 2 mip levels 1024x1024

Each mip level halves the texture resolution in both width and height.

This means:

  • Low uses half resolution in each dimension
  • Lowest uses quarter resolution in each dimension

Because texture memory scales with total pixel count, dropping one mip level greatly reduces memory usage.

For example:

4096x4096 = 16,777,216 pixels
2048x2048 = 4,194,304 pixels
1024x1024 = 1,048,576 pixels

So dropping from 4096x4096 to 2048x2048 reduces the top mip pixel count to 25% of the original.

What mipmaps are

Mipmaps are smaller precomputed versions of a texture.

A 4096x4096 texture usually contains a full mip chain:

4096x4096
2048x2048
1024x1024
512x512
256x256
128x128
64x64
32x32
16x16
8x8
4x4
2x2
1x1

The renderer selects the appropriate mip level based on how large the texture appears on screen.

Mipmaps:

  • Reduce shimmering and aliasing
  • Reduce memory bandwidth usage
  • Improve performance
  • Allow texture streaming to load only needed detail
  • Allow graphics settings to use lower resolution versions

Without mipmaps, distant textures may flicker, shimmer, or waste bandwidth by sampling unnecessarily large images.

Why power-of-two textures matter

Power-of-two textures use dimensions such as:

128x128
256x256
512x512
1024x1024
2048x2048
4096x4096

They are recommended because they produce clean mip chains down to 1x1.

Power-of-two textures work better for:

  • Mipmap generation
  • GPU texture compression
  • Texture streaming
  • Predictable memory usage
  • Compatibility with older tools and pipelines

Block-compressed formats such as BC4, BC5, and BC7 also work in fixed-size compression blocks, usually 4x4 pixels. Power-of-two textures avoid padding, alignment issues, and inefficient mip chains.

Why DDS matters

DDS textures are GPU-ready texture files. They can store compressed formats such as BC7, BC5, and BC4, and they include mipmaps.

Using cooked DDS textures provides:

  • Faster loading
  • Lower VRAM usage
  • Lower memory bandwidth usage
  • Correct mipmap support
  • Better texture streaming behavior
  • Smaller runtime memory footprint

In BeamNG, source PNG textures should be processed through the Texture Cooker , which creates optimized DDS files.

Why PNG source textures are bad for runtime

PNG is useful as an authoring format, but it is not a good runtime GPU texture format.

PNG files are compressed on disk, but GPUs cannot sample PNG data directly. Before use, PNG textures must be decoded into raw pixel data and uploaded or converted into a GPU-friendly format.

This can cause:

  • Longer loading times
  • Higher memory usage
  • Poorer VRAM usage if no cooked texture exists
  • Missing mipmaps
  • Worse texture streaming behavior

For example, a 4096x4096 RGBA PNG may look small on disk, but once decoded it requires:

4096 x 4096 x 4 bytes = ~64 MiB

That is only one texture, before considering additional maps such as normal, roughness, metallic, AO, opacity, and emissive.

By comparison, a cooked DDS using GPU block compression, such as BC7 for color textures, is much more efficient. BC7 uses about 1 byte per pixel, so a 4096x4096 texture with a full mip chain requires roughly:

4096 x 4096 x 4/3 = ~21 MiB

Cooked DDS textures are GPU-ready, include mipmaps, use less VRAM and bandwidth, and work properly with texture streaming and quality settings.

Do not ship mods with only source texture cooker PNG textures. If cooked DDS files are missing, textures may need to be cooked on the user’s machine, causing longer loading times and temporary performance drops.

Bandwidth and performance

Texture performance is not only about VRAM size. Memory bandwidth also matters.

When rendering a scene, the GPU constantly reads texture data. Large uncompressed textures require more bandwidth, especially when used on large surfaces or sampled many times.

High bandwidth usage can reduce performance because the GPU spends more time waiting for texture data instead of shading pixels.

Watch this especially on:

  • Large terrain textures
  • Road materials
  • Vehicle skins
  • Interior textures
  • High-resolution normal maps
  • Repeated detail maps
  • Materials with many texture layers

Mipmaps and GPU compression reduce bandwidth cost by ensuring the GPU reads smaller and more cache-friendly texture data whenever possible.

Relationship with Texture Cooker

The Texture Cooker converts correctly named PNG source textures into optimized DDS textures.

Recommended workflow:

  1. Author textures as PNG using the correct suffix:
    • *.color.png
    • *.normal.png
    • *.data.png
  2. Let the Texture Cooker generate DDS files.
  3. Ship the cooked DDS files with your mod.
  4. Keep material paths pointing to the PNG source path.

The game will automatically use the cooked DDS if it exists.

Materials should reference the PNG path, not the DDS path.

Example:

/vehicles/mycar/body.color.png

Do not manually reference:

/vehicles/mycar/body.color.dds

Debugging mip usage

Material debug tools show which mip levels are being used.

Use:

Material Debug Visualization → Base Color Mip Level

This view shows how much of the original texture resolution is actually being used on screen.

Use this to find:

  • Textures that are too large for their screen size
  • Objects that never use their highest mip levels
  • Bad UV scaling
  • Texture density issues
  • Wasted memory from oversized assets

If a texture almost always appears at lower mip levels, it may not need to be authored at such a high resolution.

Best practices

  • Use the Texture Cooker for textures.
  • Ship cooked DDS files with mods.
  • Keep material paths pointing to PNG source paths.
  • Use power-of-two texture sizes.
  • Avoid oversized textures.
  • Prefer grayscale textures for single-channel data maps.
  • Use debug views to inspect mip usage.
  • Test with Texture Quality set to Normal, Low, and Lowest.
  • Remember that Texture Streaming requires Vulkan or Direct3D 12.
  • Use a fast SSD when possible to reduce streaming delays.

Summary

Texture streaming, mipmaps, and DDS textures keep texture memory and bandwidth under control.

  • Texture streaming loads texture detail on demand using GPU feedback.
  • VRAM budgeting prevents the game from running out of GPU memory.
  • Mipmaps reduce aliasing, bandwidth usage, and memory cost.
  • DDS provides GPU-ready compression and mip storage.
  • Texture Quality controls the maximum mip level used.
  • PNG is useful as a source format, but not ideal as a runtime texture format.

Author clean source textures, cook them to DDS, use power-of-two resolutions, and verify mip usage with debug tools.

Last modified: July 23, 2026

Any further questions?

Join our discord
Our documentation is currently incomplete and undergoing active development. If you have any questions or feedback, please visit this forum thread.