Heightmap from numerical data

Blitz3D Forums/Blitz3D Programming/Heightmap from numerical data

Naughty Alien(Posted 2007) [#1]
..hey guys..im looking for function what can create texture heightmap(greyscale), based on numerical data from file(X,Y,Z as numbers for each point/vertex/ on terrain), and then saved texture save and use for B3D terrain with LOD...anyone can help?


Filax(Posted 2007) [#2]
Maybe you can use one of my method ? :

The heightmap texture are generally created from grey values
maybe you can use ony a file with descriptor from red value?

Each numbers are stored line by line, example :

256 ' Heightmap width
256 ' Heightmap height
1 ' Morph true or false
50,80,255,50,156,145,156,255... ' Image rgb values
70,80,255,150,156,145,56,255...
10,80,155,50,156,145,156,255...
...

etc

With this method you get many advantages, you can store
directly in your code the heightmap, or you can regenerate
easily the texture from the Red value ?

It's just my method :) not the ultimate solution :)

But if you want to generate the texture from file(X,Y,Z as
numbers for each point/vertex/ on terrain)

Maybe you can play with terrainheight function to get the
correct value and convert them to RGB.




Rob Farley(Posted 2007) [#3]
Totally untested and off the top of my head

Where I've got Z,Z,Z you'll probably be reading from an array or something, obviously this is a value between 0-255 then Z,Z,Z are the R,G,B components, Blitz Terrains only use the Red component however, it looks nicer in a paint package grey.

And you'll need the WriteRGB function below:
http://www.blitzbasic.com/codearcs/codearcs.php?code=551
HM = createimage(size,size)
LockBuffer ImageBuffer(HM)
For x=0 to Size-1
For y=0 to Size-1
WriteRGB(HM,x,y,Z,Z,Z)
Next
Next
UnLockBuffer ImageBuffer(HM)
SaveImage (HM,"HeightMap.bmp")



Naughty Alien(Posted 2007) [#4]
..well..what im trying to do is basically build 3D terrain based on scanned terrain from sattelite...so I have numerical data in simple form, X,Y,Z where actual distance between closest points is 20 meters, while height vary depending on terrain config...so I have about 30x30 km scanned area /1500x1500 points, 20 meters distance between points/..I already make it work by creating specific area chunks and then move their vertexes, whats working nice..but I am not satisfied with performance since its generated output about 4.5 million polys, so I manage to get about 25 fps based on visible area of 9x9 km where user have to choose specific chunk to see...customer is very very happy, but I want it to be more optimized so I can somehow manage whole chunk /30x30km/ at one with at least 20 fps...any suggestions, appart from approach i did already??


John Blackledge(Posted 2007) [#5]
A Blitz terrain will give a much better performance over that size of terrain - it's a good idea.

This is my original code for saving an existing terrain that had been edited within my engine:-
gridsize = TerrainSize(hEntTerrain)
img = CreateImage(gridsize,gridsize)
ib = ImageBuffer(img)
LockBuffer ib
For x=1 To gridsize
 For y=1 To gridsize
  WritePixel x, gridsize-y-1, Floor(TerrainHeight#(hEntTerrain,x,y)*16777215.0),ib
 Next
Next
UnlockBuffer ib
filename$ = "height.bmp"
SaveImage(img,filename$)	
FreeImage img


I'm pretty sure you could create a gridsize image of 1500x1500; so long as the resulting heightmap is square, Blitz should be able to use it.
So you should be able to do something like...
gridsize = 1500
img = CreateImage(gridsize,gridsize)
ib = ImageBuffer(img)
LockBuffer ib
For x=1 To gridsize
 For y=1 To gridsize
  WritePixel x, gridsize-y-1, Floor(amount#*16777215.0),ib
 Next
Next
UnlockBuffer ib
filename$ = "height.bmp"
SaveImage(img,filename$)	
FreeImage img

... where amount# is fed into the codeline for _each_ point (a value between 0 and 1).
As far as I remember *16777215.0 converts the amount to a value between 0 and 255, producing a grey scale pixel.

Where are you getting the satellite info from?


Rob Farley(Posted 2007) [#6]
John, that code would never write a pixel down the left hand edge of the image.

Also the code I post above uses writepixelfast which would be significantly faster for a 1500x1500 grid.


Naughty Alien(Posted 2007) [#7]
@Rob

In case of use only Red channel (0-255) in order to determine peaks, then how to do that here Rob (WriteRGB(HM,x,y,Z,Z,Z))?? I mean scanned return is up to 9000 meters (reality is highest scanned point 6200 meters)..so how to interpret this 9000 meters with so small resolution like 0-255?? I need this data to be accurate from extracted image..how to achieve that regarding writing down pixels in specific color, later used for B3D terrain??


John Blackledge(Posted 2007) [#8]
John, that code would never write a pixel down the left hand edge of the image.


Then mod it.
I ripped it out of my engine to get a fast answer back to Naughty.

As he says... WriteRGB()???


Naughty Alien(Posted 2007) [#9]
..I mean..I dont quite understand WriteRGB in sense that he said B3D will take only R component what is 0-255, so how to use then all of them to extract accurate data in to pixels on image??


_33(Posted 2007) [#10]
Function RGB%(R%, G%, B%)
   Return (R Shl 16 Or G Shl 8 Or B)
End Function


Hmmm, sorry, the problem seems more complex than I tought. bye.


Naughty Alien(Posted 2007) [#11]
..if B3D using only R component to determine height, then how to use R,G,B to extract accurate data?? I mean what I have to put as a input as R,G,B range equal to 0-9000 range, what can be correctly read by B3D using later hightmap??


Rob Farley(Posted 2007) [#12]
You've just got to normalise the data.

- Find the highest value and the lowest value.
- Subtract the lowest value from all the values
- Then divide all the values by the difference been highest and lowest and mulitply by 255

This will make all the values 0-255

This is the problem with blitz terrains the resolution isn't that good, which is why for my helicopter game I created my own terrain system that used a 16bit number rather than 8 bit.

WriteRGB in my first post I write:
And you'll need the WriteRGB function below:
www.blitzbasic.com/codearcs/codearcs.php?code=551



Naughty Alien(Posted 2007) [#13]
..hmm..this is about 10 meters accuracy loss since for R value there is no floats...1 meter approx in R value is about 0.1275, so everything up to 0.6 will be lost...thats bad..


Rob Farley(Posted 2007) [#14]
That's blitz terrains, 8 Bit accuracy.

Use your own terrain system, don't use one giant mesh, break it up into a bunch of meshes and Blitz will handle hiding the ones that can't be seen. You'll get a massive frame rate boost that way.

I talked about the system I used on my helicopter game here
http://www.blitzbasic.com/logs/userlog.php?user=547&log=1319


Naughty Alien(Posted 2007) [#15]
..problem is height...I cant slice height in to smaller chunks, thats where this 255 resolution 'eating' data...hmm


Rob Farley(Posted 2007) [#16]
You're completely missing the point. Never mind.


Chroma(Posted 2007) [#17]
Please continue this terrain conversation!


Naughty Alien(Posted 2007) [#18]
well...I did it, so its working just fine :) but we can keep going :)