9 Terrains, 1 Master Dynamic Heightmap - Help/Suggestions?

Morning all,

The project I’m working on involves generating procedural terrain. I’ve got my algorithms working great with one terrain object, however I want a much larger game world and rather than sacrifice LOD ability and texture resolution by stretching it across a terrain that’s really huge, I opted to tile out 3x3 terrains in a big square.

Like so:


||||
|
|||
|||___|

The issue I have is that I have one master heightmap array storing all my information (which keeps things nice and seamless), however when you call setheights, it’ll throw and error because there’s too much data in the heightmap for any one terrain chunk (eg. 1 chunk is 3200x3200 and the heightmap array is 9600x9600).

I took a stab at spinning through the array and populating a new array for each terrain chunk, but with 9 terrains - each needing a 3200x3200 array, memory has become an issue and every other attempt either ends in an array out of bounds, or GC error and Unity crash. Spiking up over 2gb just populating arrays isn’t terribly friendly on the average PC anyway…

Anyone know of an easier way to get my huge master heightmap onto my 9 terrain objects?

Thanks,
-V

Well, for starters you only need to get it once, then it’s stored in the terrain data, so you don’t have to worry about the “average PC”. Unless you re-generate it because you want random terrain or something like that.

Did you say each individual terrain is 3200x3200? Are you scaling that down or up? Because terrain must be a power of two +1 - Also, that’s pretty large, do you really need that much detail? 2049x2049 is the most I’ve ever used for anything and it’s plenty.

So scaling down to a more reasonable size would already do a lot. Applying heightmaps of that size should not be an issue. I’ve done it often.

The other solution would be to run your procedural algorithm individually for each terrain piece. You have to stitch them together anyways.

Hi Tom - the issue isn’t generating the heightmap or in applying it to one terrain object - that’s going fairly quickly. The issue is that when I generate the heightmap it’s in one array (9600x9600), but in order to apply it to the 9 terrain chunks the only way I can see to do it is to parse it out into 9 smaller array (which are 3200x3200 each) - and that’s introducing the issue. 9 array of 3200x3200 floats plus the master array of 9600x9600 floats is causing a huge amount of memory to be eaten up and occasionally crashes Unity.

What I’d really like is the ability to use SetHeights and specify only part of an array (a range for example) to apply to a terrain when called. However since it doesn’t work that way, I’m a bit stuck. Still looking for a better way to hash it all out.

I do need the terrain to be this large as I’m generating the entire game world this way - it needs to be large enough to hold all the features and provide a large play field in which players can build villages, raise armies, etc. So yeah, pretty big :wink:

-V

3200x3200 floats take up 50megs of memory. So 9 of them will take up 450megs, and since you also have a master array, thats 900 megs of space that you need. There is no way around this.

Now, to reduce the memory footprint, we can do a few things. First, do you really need float representation of height data? I bet you could get away by using a byte (scaled to your range) or at most a short (2 bytes) to denote your height.

In the case you went with a byte, you would only need 225megs of memory.

I’ll add to the discussion that creating 9 terrains that large is not really at all suitable from a memory point of view. Instead, create one master terrain height field (try to get away using just a byte), and pull out sections (in finer chunks than just 9) of it dynamically as needed by the player. This is the only way you can keep memory usage within acceptable parameters.