Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

prgrmmr

height map compression

This topic is 5769 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi! i have a very big problem. My height maps become 100MB+. Is there any way to compress it? noo, I hear you say at the moment: save it as JPEG or something else like this. It is great for monochrome 256 color heightmaps. but my height map become that complex( so the height difference became big, and the terrain became stairy), i have to store the heights at least 2 bytes. Now, i strore it as a FLOAT matrix. do you have any idea how to compress it? any type of compression, but make it smaller..

Share this post


Link to post
Share on other sites
Advertisement
Try to get ZLib and compress your stuff in ZIP, this way you won''t
have any quality loss in you heightmaps


KaMiKaZe

Share this post


Link to post
Share on other sites
Try to get ZLib and compress your stuff in ZIP, this way you won''t
have any quality loss in you heightmaps


KaMiKaZe

Share this post


Link to post
Share on other sites
yes, Kamikaze15. I''ve already tried it with Zip, but the results was depressing.

64MBb->59MB

so, Zip cannot be used, or only as a container file

Share this post


Link to post
Share on other sites
rar it, rar compression is comparably better than zip, especially for media files. I made a rar file and zip file for a folder of randomly assorted files (most of which were images) and the rar was 2.4 megs while the zip was 3.1 megs. Give it a try, the libraries for unraring are free as well.

Share this post


Link to post
Share on other sites
Well, storing something that only needs 2 bytes as a float is kind of wastefull since flaots are generally 4 bytes. Try storing them as short ints (or __int16 in VC++) and that should cut the size in half by itself. Or use some kind of compression.

If the terrain is mostly gradual changes, you might want to try difference encoding (where you encode the difference between spots instead of the full value of each). You could read in 1 byte, if its < 128, its the difference from the previous value +64 (so you do previous height+the byte you just read-64 to get the new height), and if its > 128, you subtract 128, multiply by 256 and add the next byte. In pseudo c-code:

c = readbyte();
if((c & 0x80) == 0) //fast test for < 128
{
height[location] = height[location-1] + c - 64;
}
else
{
height[location] = ((c ^ 0x80) << 8) + readbyte();
}

That allows you to have rolling hills and stuff only take up 1 byte, but also allows greater changes. If you need help on the encoding part just say so.

[edited by - Extrarius on January 23, 2003 4:09:43 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Well, the simplest approach is to simply use a less accurate data type for your points. Your original post seems to imply (although I''m not sure) that you could get by with 16-bit accuracy, even though you''re now using at least 32-bit. You really ought to try 16-bit data first, because if that works, you''ve instantly cut your map size in half. Beyond that, it really depends on the specifics of your heightmaps and needs. But I wouldn''t suggest trying something like RAR after zip fails. If you''re in the realm of 100 MB heightmaps, then an improvement of 10% in compression ration isn''t going to help much.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
If you are using 100+MB that must mean you''ve got 5120x5120 height maps.

Since you say the variation is big, why not cut this large piece into smaller pieces (like 512x512 each, ie 100 pieces).

THen you won''t get such large variations over each patch so you can use maybe 1 byte (and store a float in order to specify the start offset of this region).

You may still loose accurary, but less so than dropping from 32bits to 16bits on the whole region (probably).

That should drop you to a quarter size, 25 mb is still a lot. You can now jpeg it, or just live with the size. At least you can stream it off the disk now (one patch as you need it) so you don''t need to allocate such a large amount.

Share this post


Link to post
Share on other sites
first, really thank you for the answers. And sorry for that the composition in my message was not so accurate.

so I first started with 16bit. That means 0-65535. My height field has 1 meter spacing, so the height spacing must be less than 10cm , but 1cm would be ideal.

then a used a 32bit value. that means, if there is 65535 meters, than each meter divided into 65536. this is approx 0.1mm. But the file size become extremly large.

Anonymous Poster: yes, I use very large hmaps. I plan to use 64k*64k in my game.(huh!). Segments: yes, in my editor, I also use paging, so only few blocks(512*512) are in memory at a moment.

Extrarius: that is also a great idea, and I met this encoding way in some format before( maybe PCX, or SHP?? ).

neurokaotix: yees, and I also add it to a RAR file.

and my idea is dividing. That is, first a large 512*512 map loaded, then only the height difference between the new vertex and the average of the two neighbours.

....x.
.../|\.
../.|d\.
./..|..\.
o-------o

x is the new point
o's the olds
d is the height difference.
the dot is just spacefiller

And composing the four ideas, i'll tri to make a compression. I'll try it. ( how to draw a bulb? )

really thanx for the answers. again.


[edited by - prgrmmr on January 23, 2003 6:11:41 PM]

Share this post


Link to post
Share on other sites
Well here''s what I do:
In the map editor I work in floats.
To generate the game map where I want a small file, I keep the Min & Max values found. Then you can save the minimum value and divide Max-Min by 256 or 65536. Call this Spacing. Then each value in your floating point heightmap, you take the height h and get the map value either in a BYTE or a WORD as:
MapHeight=(h-MinZ)/Spacing
which works out as (h-MinZ)*(256/(MaxZ-MinZ))
Actually I think you''d use 255,65535!
Now you can have either 256 or 65536 levels, and it''ll automatically choose the spacing to get you the heighest detail possible. Even better if you divide the map into sections as discussed - most sections you can probably get by with 256 levels - at 10cm spacing as a maximum that''s 25m. I think 512x512 is too big for a section as you''ll be wasting lot''s of memory when much of it is not seen. I''d go for maybe 128x128. Then a 25m height change over such a smallish area is quite unlikely.
You could even have some sections stored at 256 levels and some at 65536, automatically done for you my some little utility.

Is this clear/helpful at all?



Read about my game, project #1
NEW (18th December)2 new screenshots, one from the engine and one from the level editor



John 3:16

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!