Problem
Having 27 terrains in a scene will load a large number of high-resolution textures in memory. Using up several gigabytes of both RAM and VRAM. This quickly becomes problematic on devices with shared memory. The biggest issue comes from the splat map, as each terrain can have as many as four 2048x2048 splatmaps. Each using 54MB of shared memory.
The detail map (4096x4096) is another culprit, and even less necessary since details are only displayed for a limited distance.
Unloading the terrain based on distance would be undesirable. Not only would it be highly noticeable to players, but any loading methods would cause noticeable stutters in the framerate. Simply disabling the terrain does not unload the textures from memory.
Attempted solutions
It is unnecessary to keep the full-resolution textures in memory at high distances. It’s unlikely that the full mips are even requested. Let alone appreciated at distances of several kilometers.
Mip streaming is a built-in solution to achieve this. However, the engine provides no official way to enable mip streaming on splatmap textures. Using a workaround to achieve this anyway, mip 0 is still loaded at all times.
Manually requesting mips using RequestedMipmapLevel doesn’t appear to do anything either.
The nuclear option
Setting the global mipmap limit affects every texture, including terrain splats. This has a noticeable impact on quality but should all else fail - would be an acceptable way to deal with this issue on low-memory devices.
I didn’t use terrains much but was under the impression you can make the terrain any size while having multiple terrains next to each other is primarily meant for async loading of those terrains. Did you look into async loading? Done right, it isn’t all too noticable but it may not be suitable for low end platforms (ie mobile, web).
Did you at least try it? Because that’s what most do. Or they use a custom terrain implementation respectively a world streaming asset, possibly both.
What should or shouldn’t be necessary doesn’t even matter. Unity (or any other software) operates the way it does and that defines how you can or have to work with it. Unity’s terrain system is known for its shortcomings hence why so many highly popular terrain-centric assets exist in the store, and why they’re making a new system.
I am intimately familiar with the terrain system. I’m using a custom shader, and sending splat textures to the shader manually. However, as it’s a closed source module we must rely on the advice of experts to explain the whys and hows.
Nothing has been written about mip streaming for terrain. It’s possible I’m simply doing it wrong, and mip0 must be unloaded some other way. It might also be possible to manually upload a lower resolution texture. But when the player gets close, can I load the high-res version without stutter? And how do I make sure it’s unloaded properly?
This isn’t a pressing question. It’s not a release blocker. I’m merely interested in a potential optimization.