Mip Maps do not save any VRAM memory in build, memory snapshot profiler - Riddle

Hi there! (check image below) I am trying to understand why Mipmaps do not reduce VRAM need when a texture is loaded on an object; Isn’t this what they are supposed to do? I heard lots of things (conflicting things) about Mip maps; it’s supposed to reduced VRAM memory need by loading the ‘lowest’ mip map - from the view (camera distance to object with texture on it); this low Mip Map is a ‘low res texture’ of the Full Texture…so this mip map is loaded when (camera) is ‘far’ from an textured object/the object is far in the distance – hence, only needing a low res texture/low mip map…

But, that’s not what’s happening – in the build; I checked in the editor, and I can see that the lowest mip map is loaded; I tried this example:

I put a camera very far from a plane; made a plane…with a texture on it…with streamed mip maps…I checked in the game view…and clearly, the texture on it is very low res — the lowest mip map (loaded…because the camera is Very Far…from the object);

Then, I build this, made a ‘developer build/deep profiling build’…then, I connected the build – to the Unity ‘memory profiler’; I selected to use the ‘Build’ / to get a snaptshot out of it… and clicked ‘Capture Snapshot’…and it made a snapshot.

Then, I hopened the snapshot (in memory profiler)…and checked the list of things in it…

It says: Texture2D (the texture is named: ‘test3d’) - 10.7MB…it makes no sense, this texture is 4K (4096x4096) resolution, with Streaming Mip Maps On…on it…
The Camera is Very Far…and shows the lowest mip map is loaded…then why does it say 10.6MB…that,s the Full Texture Size…in VRAM memory…

Plus, I know it’s the full texture in VRAM (and not Only the Mipmap)…
because, when I Remove mip maps…(untick ‘streaming mipmaps’ and ‘generate mipmaps’… in texture inspector)…I get 8.6MB…which is the Full Texture in VRAM (I use BC1|DC1 100% crunch compression…which reduces the texture to 8MB in VRAM (instead of 16MB…for a 4K resolution texture); then, when is it still Full 8MB in VRAM…if it’s loading not even a ‘128x128’ pixel ultral-low res ‘mip map 10’…???

If it were correctly 128x128…it would show only, like, 100kb…or 0.1MB… VRAM use for this texture – as in, ONLY, the mip map is loaded…not the Full Texture???

Please, if only can explain, because; I mean I’m going to use Mip Maps…but not if does this…I mean, there is - 0 - reduction of VRAM…by these mip maps…in fact, Mip maps incur 33% more Memory VRAM need…(when I tick off mip maps…I get 8 MB…when I tick on mip maps – I get 10.7, 11.7…which is, about 33% more VRAM memory due to ‘Generating mip maps’…

In my game, I cannot use Virtual Textures – which would save me a ton VRAM (Since I have 20s of thousands of textures 4K 8K…); so I am trying to reduce VRAM need (since I can’t use Virtual Textures, had tons of problem and the quality is awful); so I am stuck using regular textures loading on VRAM… they cost much more VRAM (than Virtual Textures); thus, to me, 33% increase in VRAM…by doing mipmaps is massive (33% x 20,000 textures…= a lot); I would only do it…if it Reduces the VRAM – by Loading ONLY the mip maps…that are needed…not loading the Entire texture in memory in the build??? It defeats the point of mip maps…if in the case it does not Only Load mip maps (not full texture in VRAM)?..20,000 textures x mip maps = saving a lot of VRAM…not if the textuers are Fully Loaded…and the mip maps are not.
I know that mip maps are ‘camera dependent’…as in if very close the camera, the mip map loads ‘mip map 0’ pretty much the Full Texture…I put a camera Very Far…to load Only the mip map…and it does not -only- load mip map…of the texture;; it loads the Entire Texture in memory in the build…Even If…the camera is very far from the object with texture on it???

As you can see the snap shot is grey with a little white sqaure (on the top left corner of the provided screenshot of it; where it says ‘Snapshot - 6384’), you see a little white square in the grey rectangle; the rectangle is the camera view…the lil white square is – the plane, with the texture on it…viewed, from afar (by camera).

Do you think this is some bug from the ‘memory snap shot profiler’?..
Or why is the full texture loaded?..if mip maps supposedly reduce VRAM (when camera is far and loads only?? a low mip map)…they don’T…from this memory snap shot capture of the final build.

Thank you very much for any help.

A MipMap does not save memory on the GPU. Not sure where you heard that.

A MipMap is a collection of textures scaled down from the largest original PLUS half-size PLUS quarter-size PLUS eighth-size, etc. In total, an uncompressed MipMap will take up roughly 1.5x the total memory that your original does.

What it will do is improve cache performance for the shader. At times in your game when your polygon is much smaller than your original texture ON THE SCREEN, it will choose to use a smaller variant of the texture stored in the MipMap, because the details would be wasted at that scale. When reading texture memory, using a smaller texture will mean that more of it fits in your GPU’s cache, so reads of the data happen faster. If you draw a polygon that is 100 pixels, it will draw faster if the texture is 128x128 than if the texture is 1024x1024, because the cache can contain more of the texture at once. When your camera moves closer to the polygon, and the polygon now is huge ON THE SCREEN, the shader will access a larger variant of the texture stored in the MipMap, so you can see all the details. All scaled versions are loaded into the GPU memory at all times (while that shader is active) because every frame may have a different need for a different scale of texture as your polygons and cameras move around. In fact, different parts of a large polygon could be using different MipMap scales, such as when your camera is near a wall and you look along the wall.

1 Like

Dear halley, thank you very much for the explanation – this is not explained, at all or (I didn’t get it, I thought mip maps when in gpu vram), in the unity manual. I thought that mip maps saved gpu vram but, as you said, it’s just shader caching small texture/fast reading/drawing improvement thing…the full texture is still loaded in memory…oh well. If you know another technique (besides reducing resolution of the texture or using Virtual Textures) that reduces texture VRAM when loaded…please do share. The only reason I am forced to use mip maps is the filtering to remove aliasing on textures, from afar; It’s great that it improves for drawing/texture reading a small version of it (As mipmap of full texture)) but it saves 0 in memory and increases 33% VRAM memory in total (33% x 20,000 textures (for total game) = Lot of VRAM); so I’m stuck either with going with low res 2k textures or using virtual textures (or doing lots of ‘chopping the level’ in little parts, which I will do, but even more; to force garbage collection, for 'garbage collection - resources asset unload; calling ‘Resources.UnloadUnusedAssets()’, to reduce VRAM growing as 4K-8K textures are increasingly loaded on GPU vram as the level goes; 4K textures will explode VRAM, is by the thousands all at same time). Thank you.

The only way to save GPU memory is to not give it data. TANSTAAFL. Everything about video game development is a choice of tradeoffs. You can’t load “20s of thousands of 4K 8K”. You will have to decide how to predict what will be visible and only give the GPU what it needs. You will have to decide how to anticipate what won’t be visible any more, so you can discard it in favor of other data.

One more question, when you say ‘discard it’ in favor of other data…do you mean, like ‘asset bundles/addressables’ that load ‘on demand’ the textures…upon ‘seen’ in the view…as the level goes. Or do you mean (somethin else) like, resources unload call to garbage collector – to remove it/destroy it. This is one thing I have difficulty understanding, this ‘instantiating and destroying’ is seen as bad, so you must do ‘object pooling’ …or, in this case, ‘texture pool/texture pooling’ or ‘asset pooling’; where you have ‘Set number’ of ‘copies’ of the asset/texture whatever…and it is ‘recycled’…instead of ‘instantiated’ (like particles) and then ‘destroyed’ which causes a ‘hic cup’ (micro-stutter) due to
the GB appearing (garbage collector’, accumulating garbaby memory resideus that need to collected by GC); I use the ‘Incremental GB’ to ‘delay it/spread it’ ‘over frames’…instead of a single frame; it helps; but, that’S the thing; like, does this also really apply with Textures loading (I mean, it is an ‘Asset’); so…I am wondering if texture pooling would help, like, I don’t even know how that works; you create a pool and add the assets/textures to it…do you tihnk this will reduce VRAM? because ‘recycling textures from memory’…or it’s pointless also; how to ‘hide’ the texture from being on GPU VRAM…I know we must ‘design’ the game ‘to hide’ thing as mcuh, as like your link TANSTAAFL no such thing as free lunch in life…but, like, if a texture appears…it is in VRAM Memory, it is ‘Instanciated?’; it is not Destroyed to be kept in memory…so does poolling the textures (insteado ‘Instantiate & Destroy’ causing GC call/memory heap increase) help there; or not. Maybe I got it all wrong…Thank very much again.

I do also know that GC being called - is to reduce the memory heap increasing, like VRAM increasing…iwth many textures loaded ‘over time’ as level goes…but, is pooling better then? for textures, in terms of VRAM…if GC reduces VRAM…that’s good…but I would need to ‘destroy’ textures all the time?..or do the Resources Unload Call of GC…remove All the textures in memory…??

If you know an asset that can ‘load/unload’ textures ‘upon seen/unseen’ please I would love to know; like, Unity Addressables that load/unload assets ‘on demand’…do you know? This could help in ‘destroying/hiding’ textures when they are not in the view anymore…I was told that the GPU VRAM still increases – even if – we use Unity Addressable; as in, it does not ‘Unload’ texttures from GPU VRAM…it only ‘loads’ on demand…as we arrive in front of the texture…then, the texture is added to the GPU VRAM Total…and it does not decrease it…?..that, you still, need to call Resources Unload Asset …to reduce GPU VRAM…(Addressable does not reduce GPU VRAM ‘total tally’ (it only ‘loads incrementally…things as they come’ in the VRAM memory; if the level is long…by the end of it…Everything will have been loaded, no matter if Addressables or Not…because you needed all the textures to be shown; hence, VRAM total will be maxed)…only Resources Unload.AllAssets(), call to GC does to reduce VRAM)?

The Memory Profiler version/Unity version you’re using doesn’t actually distinguish between RAM vs VRAM as it doesn’t have that information yet. That was added in 2022 and version 1.0 of the Memory Profiler. So this could be CPU memory for all we know, and the CPU will need to have all of the mipmaps handy in case the GPU needs it.

Newer versions of the Engine & Memory Profiler also provide additional metadata (in the Selected Item Details panel) for textures, such as the midmap level loaded at the time of capture