Game Development Community

16-bit Heightfield in TGE Terrain?

by William Todd Scott · in Torque Game Engine · 05/02/2006 (8:24 pm) · 9 replies

OK,

One more terrain question...

Is it terribly difficult to allow 16-bit heightfields in TGE or in the 'TGE Terrain' code that is in TSE?

I understand that changing the size of the heightmaps from 256x256 is quite a challenge, but maybe this would be more manageable?

If so, I'll tackle it...I just don't want to waste a week to find out that it involves modifying assembly code and completely rewriting the entire terrain engine! :)

edit: Adding the following question:

At first glance it looks like this might not be a beast to change. The Terraformer::loadGreyscale function has the following bit of code:
dst->val(x, y) =  ((F32)rgb[0]) * (0.299f/256.0f) +  
                          ((F32)rgb[1]) * (0.587f/256.0f) +
                          ((F32)rgb[2]) * (0.114f/256.0f);
Can someone explain this to me? If this function loads an 8-bit greyscale image I would have expected it to just take the rgb[0] byte as the 8-bits for each pixel and throw out the rest.


Thanks
Todd

#1
05/08/2006 (7:39 pm)
That's the most common formula for RGB to grayscale conversion. (It's based on how the eye perceives brightness or intensity.) In order to accurately create the brightness and contrast of the original image, you have to take a percentage of each channel. If you were only reading the red channel (rgb[0]), the grayscale image would not look right. Search the 'net for something like "RGB to Grayscale Conversion Formula" for more info.
#2
05/08/2006 (8:16 pm)
Thanks Kevin.

Todd
#3
05/25/2006 (8:32 pm)
Ummm, I think the heightmap is actually 24 bit. RGB values are weighted in a bit order. Search on the TGE forums and it will tell you somewhere.

The code you showed actually explains the bit weight:
dst->val(x, y) =  ((F32)rgb[0]) * (0.299f/256.0f) +  
                            ((F32)rgb[1]) * (0.587f/256.0f) +  
                            ((F32)rgb[2]) * (0.114f/256.0f);

The green would be most significant, the red next and the blue last. The problem is creating a program to smooth out the values. However you could build a program that creates a height map and then converts to the RGB image with the appropriate values. To see this in action create a solid green image with only the green component at a value of 127. Next put a dot in a corner where green is 0 and another dot in another corner where green is 255. Now go to the center of the image and change 3 pixels to (0,128,0) for RGB on one, (0,127,1) on another, and (1,127,0) on the third. If you put them next each other you should see a step pattern.

I forgot, use this image as a bitmap when creating a height field.
#4
05/25/2006 (8:41 pm)
edit: Note, as Frank points out below, this post is more theoretical than others in this thread, so if you're actually trying to implement this in the short-term in torque you might want to skip this one. :)

To expand on what frank says,
if you were able to create an image where red is the most significant components, green the next, and blue the least,
then a conversion function like this would get you 24-bit precision:
(pseudo-code)
height = ((r * 2^16) + (g * 2^8) + (b)) / (2^24);


however,
as Frank says, making such an image will be kind of a task.
#5
05/26/2006 (9:41 am)
The file terrData.h defines height values as U16 which are 11.5 fixed point values. And it says this near the bottom:
// 11.5 fixed point - gives us a height range from 0->2048 in 1/32 inc

Your equation seems to convert the grayscale to a floating point value and terrData.h converts it to a 11.5 fixed point value with:
inline U16 floatToFixed(F32 val)
{
return U16(val * 32.0);
}
So it appears terrain is scaled from 0-2048 not 0-256.

However, if your map is a mile x mile x mile then it doesn't do much good to have 20 foot horizontal resolution (1 mile / 256) and 2 foot vertical resolution (1 mile / 2048) or 1 inch vertical resolution (1 mile / 65536).
But it's sure worthwhile to experiment with gray scales to see what they can really do.
#6
06/01/2006 (7:03 pm)
Mike:
I did not realize it the effective resolution for the height was that low. That is good to know especially if you end up creating a terrain program that operates with the full effective resolution. I dissagree that it doesn't do much good to have a higher resolution for terrain height. It allows you to make much smoother terrain. At the very least use a 256 resolution height field and smooth out the transitions so it looks nice. When I was first building terrain height maps I could not figure out why they were stair stepped. When I started seeing how the engine handled the bitmap with the RGB values having a weight, then I understood why. So you really can't ignore it if you want your levels to look nice.

Orion:
I am fairly certain that the bitmap function in the terrain editor has green weighing the most. I am only pointing that out because your example might cause confusion. I understand that your are speaking conceptually about what I originally thought was true, but is false about the amount of resolution actually available.

Kevin:
Are you sure that is true? Every greyscale file I have ever seen is equal values for each shade of R,G, and B. Thus, if R,G, and B are 8 bit you would have 256 shades of grey with each color component being the same value for each individual shade. Example: 255,255,255 = White, 0,0,0 = Black, 127,127,127 = Mid Grey.
#7
06/01/2006 (7:15 pm)
Mike,
I had time to think about it and the terrain is 11 + 5 = 16 bits of effective resolution. So it is 65536 levels of elevation possible not 2048 (2048x32 = 65536 = 2^16). That makes for "very" smooth terrain. So I guess the resolution is not as low as I originally thought when I read your post.
#8
06/02/2006 (8:26 am)
Frank - good point. i edited the post to warn the unwary.
#9
06/02/2006 (9:06 am)
That's right. If the map units is meters, then a 11.5 fixed point number would be 0..2048 meters in 1/32 meter increments. Which is 65536 possible increments. Having a high res Z axis does help a lot, but not as much as having medium res on all three. But what I'd really like is to skew the grid points themselves, so I could have fewer points in flat areas and lots of points in hilly areas, and even have a point directly above another so I can have a vertical cliff.
I don't know why Torque would bother with the above equation ( where R=.299, G=.587, B=.114 ) if it's expecting us to use a gray scale. After all, 127.127.127 is still 50%, no matter what the equation. Only a photo editor would care about exact perception of the human eye. But since green is half the total, I'd vary the green as most-significant-byte and keep red-blue together as least-sig-byte, that'd be pretty easy.