Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Discussion / Vast scrolling heightmap

Author
Message
Link102
19
Years of Service
User Offline
Joined: 1st Dec 2004
Location: On your head, weeeeee!
Posted: 20th Nov 2009 02:48 Edited at: 23rd Nov 2009 15:49

I've done it! Haha I've mastered the heigtmap.
By using memblocks to read rgb data and converting that to a height value. I've managed to get a 2000 x 2000 terrain on a 50 x 50 matrix :3. Can you smell the opportunities? This would be great for a dune racer or a (dare I say it) mmorpg.
go and have a looksy (download button bottom right) and tell me what you smell

things to do:

- 8 bit bmp support (reading a grayvalue instead of a rgb value is faster, rgb value is multifunctional)
- convert the heightmap to a mesh instead of a matrix. (to hopefully boost speed)
- textures (tinker with the uv's, dunno if it will work)
- shadows (either a shadowmap or textured in or calculated one that works with normals)
- weave in difrent levels of detail. (the far away stuff doesn't need much detail)

edit: be sure to check the update 4 posts below.

- Link102

Attachments

Login to view attachments
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 20th Nov 2009 17:31
Very nice technique. Nice and concise. Good work!

Just throwing this out there as some other ideas: the use of a single heightmap image has a few limits - including speed, size, memory usage (at once). A variation for virtually unlimited size would be to use a series of smaller sized heightmaps, say 256x256 or even smaller. Load them into the memblock on demand - or convert them into arrays ahead of time and load in the data as arrays on demand based on virtual matrix position.

Thanks for posting this. It's easy to see what you did in your code. I'm gonna have to play around with this idea.

Enjoy your day.
Link102
19
Years of Service
User Offline
Joined: 1st Dec 2004
Location: On your head, weeeeee!
Posted: 20th Nov 2009 18:16 Edited at: 21st Nov 2009 15:25
Quote: "Just throwing this out there as some other ideas: the use of a single heightmap image has a few limits - including speed, size, memory usage (at once). A variation for virtually unlimited size would be to use a series of smaller sized heightmaps, say 256x256 or even smaller. Load them into the memblock on demand - or convert them into arrays ahead of time and load in the data as arrays on demand based on virtual matrix position."

I've thought about that. Perhaps I'll add it in the future. It'll go right in with the variations in detail. I'll probably change the code to load 10 tiles instead of each one.
Sidenote: I dont think an array would be that much faster than a bitmap (8bit), because a bitmap is just a strain of numbers with a header.

Quote: "I'm gonna have to play around with this idea."

That's exactly why I'm posting this

I'm working on creating objects from memblocks. so far I've recreated the plain object successfully. Just gotta flip it on it's side and make a matrix out of it.
edit: added a picture of the plain
edit2: well I've accidentally saved a different project over this one. Back to square one T_T
edit3: I don't want to lose this again.


- Link102

Attachments

Login to view attachments
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 20th Nov 2009 20:04
Quote: "Sidenote: I dont think an array would be that much faster than a bitmap (8bit), because a bitmap is just a strain of numbers with a header."

I was thinking about that. But if you want the height to be more than 255 units, you have to use some kind of multiplication or other maths to scale the height. If you use a 32 bit value, or even a 16 bit value, you can eliminate the scaling and just store the actual desired height either in an array or a block of memory. Assumingly, on your 50x50 matrix, if you want a wider lanscape at a time, instead of make matrix 1,500,500,50,50 you wanted make matrix 1,5000,5000,50,50, you'd have to do a multiplication for each vertex that you wanted to scale. In this example the height would be 10x higher. So the total number of multiplys would be 51*51 or 2601 per matrix update.

So perhaps, precalculating the height values and storing them somehow for whatever size matrix one will use might cut down the in-game overhead.

Oh, and I noticed you were getting the height and width of your image from the memblock the hard way:


You could just


Enjoy your day.
Link102
19
Years of Service
User Offline
Joined: 1st Dec 2004
Location: On your head, weeeeee!
Posted: 20th Nov 2009 20:11 Edited at: 20th Nov 2009 22:25
Quote: "you have to use some kind of multiplication or other maths to scale the height."

that's the "/ 3" at the end of line 50 where the height# value gets asigned. (note the code is mean for a 500*500 matrix, it's not open to bigger ones yet). It's not the actual height that gets changed, it's the detail that you can change it. 8 bit has 256 steps, 24 bit has 256*256*256 = 16777216.
Quote: "Oh, and I noticed you were getting the height and width of your image from the memblock the hard way:"

hmm maybe I should read the rgb values as dwords too, so you'd still have the detail and the speed. Thanks for the tip.
The reason I used bytes was because I was unsure about dwords. I'm still learning about dwords, floats and all that stuff.

Latch, do you have any ideas for a blended texture?

update: (just performance, no new functions)


Your signature has been erased by a mod - Please reduce it to 600x120 maximum size

Attachments

Login to view attachments
Link102
19
Years of Service
User Offline
Joined: 1st Dec 2004
Location: On your head, weeeeee!
Posted: 21st Nov 2009 16:17 Edited at: 21st Nov 2009 19:05
well here's a litle update (save attachment as "texture.jpg")

You might be wondering "what is this?". This, my dear friend, is a 1 sided mesh matrix, that doesn't have the limitations that normal matrixes in dbc have. It's made by writing to memblocks then converting the data to a mesh. Go and have a play with it, like this: matrix(1,1000,1000,100,100). It can support up to 254*254=x segments (as long as x stays at 64516 max) wich is more than necessary (or safe).
Now if you don't mind, I'll have to check in at a hospital, because I've cracked my brain.

ps. if you come across a bug please let me know.
ps2. I'm thinking of writing a tutorial about memblock meshes when I'm done.

- Link102

Attachments

Login to view attachments
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 21st Nov 2009 18:45
Quote: "Latch, do you have any ideas for a blended texture?"

Yeah, actually. I've tried a couple different things in the past. I'm trying to find a method that can create good detail for up close, and general detail for far away. The up close part is hard because the only thing I can come up with is creating individual textures for each tile that are unique to the specific heights. Even on a small terrain such as 10x10, that would mean 100 textures which may eat of processing when you want other things going on in the game. It's a blanacing act.

Anyway, as far as blending techniques, there's a couple ways you might approach this.
1. Create a fixed number of blended textures ahead of time. Say you have 4 different terrains: water, sand, grass, and rock. Based on a height map, you have ranges within 0 to 255. Divide 255 into 4 groups that represent the height range of a particular terrain. Let the ranges overlap a bit.

For example, water is set to a range of 0 to 30, maybe sand is in the range 20 to 80. You make grass have a range of 70 to 200, and you make rock have a range of 180 to 255. Based on these values, you create a series of predefined blended textures. Maybe you want 20 textures. Divide 255/20 = about 13.

So, at 13, your 1st texture would be a pure water texture.

At 26 you would blend sand and water based on a percentage. Water runs 0 to 30 and sand starts at 20. So the percentages for each texture might be calculated as
((30-20)/100)*((30-20)-(30-26)) = .6 for sand
and
1 - .6 = .4 for water

You create a new texture by looping and grabbing the pixel color in the same position of each texture and alphablending them based on the percentages.

Then you check the next value increment by 13 (remember, we want 20 predefined textures based on any hieght from 0 to 255 - so that's increments of 13)

At 39, that would be pure sand. It's not until the 6th texture does grass start to make it's appearance = 78.
((80-70)/100)*((80-70)-(80-78)) = .8 for grass
and
1 - .8 = .2 for sand
And you continue until you create your 20 preblended textures. Hopefully, the 4 original textures were all seamless so they could be used to repeat.

Now, based on your heightmap, or the tile height of your terrain, if the height falls withing the range of a predefined texture, then you texture that cell. The ranges for the 20 textures are based on heights from 0 to 12, 13 to 25, 26 to 38, and etc.

2. Use preblended textures but texture the terrain by hand for better control. For this method, take a look at:
Blending Textures
The code here will take 2 textures and output 12 preblended textures. You can use the textures to create a fairlywell blended landscape but you'd have to do it by hand.

3. Create terrain specific textures by using the heightmap to blend multiple textures together. This is similar to method 1 from above. The difference is you create a master texture by blending multiple textures together based on the heightmap. Unlike method 1, the percentages weighed are pixel to pixel instead of entire texture to entire texture. This results in a much smoother blended texture but is much more expensive in terms of processing cost depending on the size of your resulting texture(s).

Enjoy your day.
Link102
19
Years of Service
User Offline
Joined: 1st Dec 2004
Location: On your head, weeeeee!
Posted: 21st Nov 2009 22:10 Edited at: 21st Nov 2009 22:11
what I'm looking for is this

wich I believe is method nr 3.
I'm looking for an effective way to do it or the way valve did it in their engine (the source engine)

- Link102

Attachments

Login to view attachments
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 22nd Nov 2009 02:34
From the look of the picture, it looks a lot like No. 2 for the blending method (if you tried out the code). I say that because of the squareness of the blend. Could be like No. 1 But it's hard to say. I would be guessing.

I'll attach an example of terrain I'm using in the DarkPros thread. This is blending method 3 using 3 textures.

Enjoy your day.

Attachments

Login to view attachments
Link102
19
Years of Service
User Offline
Joined: 1st Dec 2004
Location: On your head, weeeeee!
Posted: 22nd Nov 2009 02:55
What valve did was give each vertice a value, probably 0 to 255. 0 being completely grass and 255 being completely stone.
What I'm wondering is should I build the blended textures ahead of time, resulting in 4228250625 texture files. Or should I treat it as one big texture like a texture map. Or should I build the textures at runtime resulting in lag?
Again, how did valve make it? or is it some kind of build in feature of directx?

- Link102
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 22nd Nov 2009 04:27
If it is as you say, then it's probably like No. 1 except maybe more textures (maybe even 255 !) Then as the terrain is drawn, look at the lower left vertice of the tile and choose the texture for that height/cell - I'm assuming DBC. If it's done in Direct X then you have more options including rendering textures and alpha blending per drawn triangle.

If it's Direct X directly, as each triangle is rendered, you can look at the "heights" of the vertices. One way based on the heights, you alpha blend the textures as you render the triangles. When the complete mesh, in this case the terrain, is drawn to screen, the textures are blended.

For DBC, the options seem limited without resulting in ginat overhead in terms of texture size or sheer number - or resolving to use a managed number prerendered textures based on 0 to 255

Enjoy your day.
Link102
19
Years of Service
User Offline
Joined: 1st Dec 2004
Location: On your head, weeeeee!
Posted: 22nd Nov 2009 15:57
So it's either tiles or a texture map.
dbc has it's limits sometimes...

- Link102
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 22nd Nov 2009 17:42
Don't take my word for it. I have a few ideas because this is something I've been struggling with myself. There are probably ways to do it in DBC - just haven't figured them out yet; at least how to do them efficiently.

Enjoy your day.
Pincho Paxton
21
Years of Service
User Offline
Joined: 8th Dec 2002
Location:
Posted: 22nd Nov 2009 23:31
It looks good... now where do I get the data for Mars...

Link102
19
Years of Service
User Offline
Joined: 1st Dec 2004
Location: On your head, weeeeee!
Posted: 22nd Nov 2009 23:48 Edited at: 22nd Nov 2009 23:54
a mars heightmap can be found here
you should be able to load it if you replace the heightmap.bmp image by this one.
Just be sure to convert it to a 24 bit bmp

- Link102
Pincho Paxton
21
Years of Service
User Offline
Joined: 8th Dec 2002
Location:
Posted: 23rd Nov 2009 18:14 Edited at: 23rd Nov 2009 18:18
Thanks! Very flat isn't it.


Link102
19
Years of Service
User Offline
Joined: 1st Dec 2004
Location: On your head, weeeeee!
Posted: 23rd Nov 2009 18:23 Edited at: 23rd Nov 2009 18:25
Well it only looks flat because the map is scaled down a couple thousand times.
But if you absolutely want bigger mountains you could decrease the "/49344" value

- Link102
Pincho Paxton
21
Years of Service
User Offline
Joined: 8th Dec 2002
Location:
Posted: 23rd Nov 2009 18:34
Thanks! How do you make the mesh bigger?

Link102
19
Years of Service
User Offline
Joined: 1st Dec 2004
Location: On your head, weeeeee!
Posted: 24th Nov 2009 04:29 Edited at: 24th Nov 2009 04:31
what are you up to?


- Link102
Pincho Paxton
21
Years of Service
User Offline
Joined: 8th Dec 2002
Location:
Posted: 26th Nov 2009 22:23
No the mesh size? The square is too small.

Link102
19
Years of Service
User Offline
Joined: 1st Dec 2004
Location: On your head, weeeeee!
Posted: 27th Nov 2009 17:16
lol XD

make matrix 1,500,500,50,50
to
make matrix 1,5000,5000,50,50

Login to post a reply

Server time is: 2024-04-25 12:43:12
Your offset time is: 2024-04-25 12:43:12