Carmack's MegaTextures

I totally agree with you ebray (Kevin), but coming up with a streaming technique is not trivial especially if you want incremental changes in the texture e.g. texture LOD changes from L to L + 1. An efficient scheme needs to be devised to handle this gracefully especially with the viewer moving quickly across the terrain surface. I, for one, do not like texture clipmaps simply for their enormous software overhead. Geometry clipmaps are better and perhaps a better implementation of the clipmap technique, but it suffers from an inherently conservative culling technique and poor batch submission (in comparison to a fixed sized patch approach) and almost always gets CPU bound.

Basically, what I’m saying is:

Divide the large texture into smaller ones.
Correct UVs on the geometry (adding new verts when necessary) to use the textures.

When running:
Load all textures ignoring their top 3 mip levels.
When an object passes a certain size threshold on the screen, send an order to a separate thread to load the top mip levels needed.
When that order is finished, change to use the texture that contains the mip levels needed.

The worst case for this algorithm is that someone gets a lower res texture than is desired and then the higher res one pops in later. With a naive implementation of this, I’m sure you’d see a lot of popping. A lot of work would probably be needed to ensure that the texture data is stored in such a way that is fast to read off of the disk.

Another limitation is seams that can’t be filtered accross, since you can’t filter across multiple textures obviously, but this probably isn’t the worst problem in the world, especially with noisy textures like those you’d see on terrain.

Kevin B.


I was thinking about something like that too.

A huge percentage of a scene is made up of lower rez mipmaps, so many higher rez ones aren’t really needed. By ‘decoupling’ mipmap levels from each other and perhaps doing mipmap filtering by hand in a shader, you should be able to make much more efficient use of texture memory. Worse case mipmap level for each ‘block’ of a terrain/scene could be computed by block distance from camera, and you could let texture management do all the work!

But perhaps hardware already does this? When a texture is ‘evicted’ from vidmem, does the whole thing+mipmap levels get tossed or just the LRU mipmap level. I suspect the former but the latter would make for a nice optimization!

When a texture is ‘evicted’ from vidmem, does the whole thing+mipmap levels get tossed or just the LRU mipmap level.

I think a texture is still linked deeply to all its mipmap levels.

Carmack already talked about this 6 years ago, in a plan stating :
“Virtualized video card local memory is The Right Thing.”

The whole discussion is still very interesting :
(bottom of the page)

“The primary problem is that textures are loaded as a complete unit,
from the smallest mip map level all the way up to potentially a 2048 by
2048 top level image. Even if you are only seeing 16 pixels of it off
in the distance, the entire 12 meg stack might need to be loaded.”

Funny how with MegaTexture shaders it seems to be possible to re-implement the videocard low-level cache policies :smiley: