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.

Newcomers DBPro Corner / Heightmap Generation & Linking Heightmaps Together

Author
Message
Joker436
12
Years of Service
User Offline
Joined: 18th Mar 2012
Location:
Posted: 27th Mar 2012 18:54 Edited at: 12th Apr 2012 08:52
Hello all,

First I want to say thanks to TGC... I've been totally enthralled with this language since purchasing the software... I can't explain why, but writing code in this language is just fun. Two thumbs up, folks!

Ok, on to my questions. I apologize in advance for the length of this post.

I'm working on terrain generation. I've checked out a number of ways to handle it, and it seems heightmaps are the way to go.

Am I correct in that thought?

In my messing around with code I've written and code that I found out on these forums, I found 2 great bits that I've been playing around with:

Memblock Image Manipulation Library:
http://forum.thegamecreators.com/?m=forum_view&t=172059&b=6

Heightmap Generator code here:
http://forum.thegamecreators.com/?m=forum_view&t=176809&b=1

What I'm trying to do is use a seed heightmap image to then generate neighboring heightmap files that could, in theory, be linked together in a 3d scene to form a seamless, random terrain. I'm trying to do this by taking an (x) number of pixels from whichever image edge I want to seam from and then applying those pixels to a new image (in the final product, in reverse order) which then is filled in by random generation that accounts for the pre-existing values brought in from the first image. Does this make sense?

I've got a prototype that sort-of works based on code in the 2 forum posts above, but it's not quite working right. I've attached a zip file that contains the MAP_SEED.jpg image and a resulting image that gets created. The code currently looks at 25 pixels of the seed image:



Am I on the right track here? It seems like it's kind of close... except for the clear and obvious line where my paste of pixels ends and the randomization begins... LOL. The pixel order has not been reversed yet either... I've mainly been trying to see if this is even possible before moving forward any further.

I'll also apologize in advance for things like not cleaning up my objects/variables after using them and any messy/bad coding conventions. In final code I clean up my variables, but for prototype code I just go to town and not worry so much, so please excuse that.

Could anyone possibly give me a hint as to what I'm doing wrong here? Any help or suggestions would be greatly appreciated!

EDIT:
I changed the initial pixel value from 255,255,255 to 0,0,0 and am seeing some better results.






Here's some code:

Attachments

Login to view attachments
29 games
18
Years of Service
User Offline
Joined: 23rd Nov 2005
Location: not entirely sure
Posted: 28th Mar 2012 21:47
I've started to have a look at this but have to go out in a minute so haven't got far.

If I understand correctly, you've managed to: get the data for the edge pixles of the seed image and then used this to start a new height map image. What your asking for is for some idea to create a smooth out the new height map image or to make it look more natural, is that about right?

Right, have to go and I'll get back to this later.
Mulderman
20
Years of Service
User Offline
Joined: 8th Jan 2004
Location: C:\\
Posted: 29th Mar 2012 23:46
If i were you, i would try BMP or PNG instead of JPG.
And see if you will get better results.
Joker436
12
Years of Service
User Offline
Joined: 18th Mar 2012
Location:
Posted: 10th Apr 2012 17:42
Hey folks thank you for the responses and apologies in the delay in response. I've been head down in DBP messing around and learning how things work. Apologies on this long post... this has really turned into a bunch of questions for me.

@Mulderman - thank you... I did some more searching and found information about how JPG compression creates image artifacts which can be interpreted as bumps by the terrain object in DBP. Using a BMP or PNG apparently will resolve that. It's on my TODO list to change that code over to PNG.

@29 games... that's the basic premise. I actually have the image generation part working now (in one direction). I'll update the code here later today. The seams are not perfect, but I believe that's due to me using JPG images.


The thing is, I am not sure using heightmaps in this way was the right way to go when talking about terrain generation on a large scale. As another test, I generated 4 random heightmap images and added 4 terrains to a program... the memory usage was off charts.

I'm wondering if the terrain object is really meant to be used more than 1 time in a program. Could anyone shed some light on that? My thinking right now is that heightmaps are GREAT for generating a big big zone, but it's just that - a zone... not a sprawling landscape model. Yes? No? Slap me?

When I saw how much memory the terrain was using, I looked into other ways and have been messing around with 2 options.

1. Matrix - The matrix system I have right now shifts (up down left right) and moves positions as the character moves around. Right now it will let you walk forever over the 2000x2000 by 200x200 segment matrix I created. I found some code out here and bastardized it and utilized the Perlin Noise plugin I found out here to generate random height values. It works... but meh... it looks crappy. Too many segments = alot of memory usage which is no good. But to get nice rolling terrain instead of pointy, early-90s terrain, one needs more segments to accomplish that.

I also found an example where a guy used 100x100 matrix "chunks" with 64 segments each in a 100x100 grid that generated something that looked great did not use much memory at all. I like that one... except for trying to generate new terrain to add to it and remove from it as a character moves... ooof.


2. Memblock->Mesh->Object: This has produced the best looking, lowest memory consumption object - and it seems like I'd have a ton of control... but with so many options that at least on the surface look like they are meant to handle terrain, I'm wondering if this is the right way to go or not. I didn't take it any further than creating the memblock, mesh and plain object with random perlin noise heights.


At this point I'm really asking myself which is the right direction to take. They all seem to have pros and cons so I almost wonder if I'm overthinking it too... just pick a horse and ride it, ya know?

Anyone have any thoughts or suggestions on this? Is it a case of "No no, you silly new guy... with DBP most folks generally do it like THIS", and I'm just missing that?
WLGfx
16
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 12th Apr 2012 02:20
@Joker436 - If you mean my Perlin Noise plugin, it actually has a very small memory foot print. And with the addition of the Simplex Noise, which is separate, it's smaller again and almost 20 times faster. ( Found here ) A few more examples added too.

I'm just finishing off a video renderer plugin and I'll be updating the Simplex Noise plugin to whatever people would like adding to it.

Using Matrix commands is probably the easiest method but texturing it can get annoying. And it's probably the fastest. I've found that even with generating 256 separate tile textures it doesn't look perfect. I can add a function to generate the height of a MATRIX and calculate the vertex normals in real-time, which is what I plan.

The idea too about breaking them up into smaller chunks can be used for culling distant objects and speed up rendering.

Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!
Joker436
12
Years of Service
User Offline
Joined: 18th Mar 2012
Location:
Posted: 12th Apr 2012 09:30
@WLGfx - I was definitely not meaning your plugin... I've only used the perlin noise plugin (now I will go try Simplex as well!) and have been ultra impressed with what it does. In my mind (I am also quite new here), I don't need anything else to randomize pretty much anything at all. I can't wait to try it out on other things aside from terrain as I learn more.

I apologize if it came out like I pointed at your plugin being bad... definitely not the case!

Is it just that the textures don't line up properly or...? I haven't even gotten that far yet. I'm still trying to grasp what I think are the basics.

With regard to my matrix, as it turns out it's my noobness that was at play there. *blush* The proportions of my matrix were what caused things to look the way they did. A case of "math failure" on my part.

I jumped on the matrix horse. It just seems to make sense and seems to be the consensus for new coders. I'm working with a matrix that is 65,536 x 65,536 with 256 segments on X and Z. It's looking better for a non-textured terrain.

I set some lighting and found some code to (I think?) determine normals that I turned into a function to call. I'm having trouble grasping the concept of normals... I get that they determine how the object takes light but that's about my depth right now. This is a big one on my seemingly longer 'to do' list of things to learn.

I've updated the original heightmap code. I was able to get 3 256x256 heightmaps generated from a seed file and 'linked' together (lined up next to each other - lol) at around 80MB of memory usage.

I'll also be glad to share the matrix thing too, but it's really nothing groundbreaking. I guess until someone gives me reasons otherwise, I'll continue down the matrix path. My next learning endeavor is to save height information and try to read/write map data.

@WLGfx - your plugin is amazing and I can't wait to try out Simplex. Thank you!!
WLGfx
16
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 12th Apr 2012 17:04
If you do go down the Matrix route which is easier to code and you decide to use the Simplex Noise plugin then I'll get a function that creates the heights from the simplex noise and also generates the vertex normals for the lighting.

I'll try to remember later today to dig out the code that generates the 256 tile textures for the matrix too. It takes a 256 x 1 pixel gradient image and creates the textures from it on a grid texture of upto 4096 x 4096.

As for saving the height information there shouldn't really be any need to because all you need to save is the noise parameters. One thing I do need to add the the simplex noise plugin is a table shuffler for the random seed value.

There are also a few more things I'm considering for the Matrix terrain code.

1. Create a 3x3 or 5x5 (or whatever) grid Matrix's and LOD them so that the middle grid is the highest detail.
2. Partial updating of the Matrix. (ie shift values up/down/left/right and just update a single edge)

Probably a few more ideas will come to mind.

Matrix is easy to use because DBP had the built in Get Ground Height() function.

I'll get back to you as soon as I find that texture code and also when I update the Matrix side of the plugin.

Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!
Lewis999
13
Years of Service
User Offline
Joined: 23rd Oct 2010
Location:
Posted: 12th Apr 2012 18:30
After reading this thread, I personally think the best way to achieve this would be to make terrain the generates as you move using arrays => memblocks => mesh => object, using the matrix1utils plugins you can save the arrays to datafiles. First of all, you could have a function to generate blocks of terrain, first checking if any blocks around it exist, and if they do copy the data from the edge of that block to the new one, generate it using that data and saves an array with all the heights in (block(x,z)=y). Then have a second function that loads the array, and makes an object out of it using memblocks. using memblocks means it is easier to set the uv values, so you can set the texture of each tile separately(eg. check the height difference between the 2 corners, and if it is more that a certain number(meaning the terrain there is very steep)set it to a stone texture.)

When the program starts it generates a grid of "blocks" like:

, and inside the loop the program checks the players position, and if they move out of the block they are on, it deletes the row/column of blocks behind them, and generates a new row/column in front of them. I'll post an example of something like this soon.

Anyway, this is only one way of doing it, (It just happened to be the same way as something I've been working on ^^) and using matrixes would work fine

Quote: "I also found an example where a guy used 100x100 matrix "chunks" with 64 segments each in a 100x100 grid that generated something that looked great did not use much memory at all. I like that one... except for trying to generate new terrain to add to it and remove from it as a character moves... ooof."

It's easyer than it sounds

That's from a project i'm working on, it's called every loop and uses coroutines to smooth it all out.
it's a little more complex than it would need to be, and it also deletes tree objects and other things on the terrain, but you get the idea >.<

hope this helps, even if just a little. as I said, I'll post what I have so far when I get it working properly
(having some problems right now, but I have most of it working smoothly)

Lewis
WLGfx
16
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 13th Apr 2012 03:20 Edited at: 13th Apr 2012 03:26
This is the function that creates the 16 x 16 (a total of 256) texture tiles from a gradient bitmap that I used in my recent bike game. Attached is the bmp file of the gradient but you can use any art program to create a gradient.

Okay, it's in C++ but should be real easy to understand and convert to DBP. I do actually have the DBP code around somewhere, most likely on another computer because I wrote the bike game in Dark Basic Pro, Dark GDK and Pure GDK.



This simply creates procedural textures using a very simple method. And if I can find the DBP project or the link I'll come back.

EDIT: DBPro 3D MotorChase by WLGfx which includes the full source code and media... (And I've never updated it to use the faster Simplex Noise.)

Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!

Attachments

Login to view attachments
Joker436
12
Years of Service
User Offline
Joined: 18th Mar 2012
Location:
Posted: 14th Apr 2012 03:07
@WLGfx

1. Create a 3x3 or 5x5 (or whatever) grid Matrix's and LOD them so that the middle grid is the highest detail.
2. Partial updating of the Matrix. (ie shift values up/down/left/right and just update a single edge)

These are 2 ideas I've tossed around as well (not the LOD part, that would be way cool though).

I considered number 1 but I thought it would harder to manage multiple matrix objects with each their own segments as I moved around the 'planet'. I also figured it would remove my ability to use the shift matrix command because as well... not sure on that though.

My reasons for wanting to save the height info (and maybe I am misguided?) was I didn't want the same noise params for the entire 'world', I never want the same world twice, and once a world is created I want to be able to share that world's data with a friend easily.

Would it be easier/better/faster to save the noise params with coordinate bounds instead? Since you mentioned it, I've been torn on that. Right now my model is 5 bytes per point. 4 bytes for the float height and 1 byte for a biome marker (sorry for the minecraft term). Based on my calculations, a 4x4 (16 'blocks') of 256x256 segments comes out to 5MB saving the height + biome point by point.

The whole biome marker was to give me a point where different environments exist in my little world. My intention is to determine seed locations for x number of biomes on the planet and then use some loops to fill in the spaces in between as randomly as possible while still making sense (no ice environment in the middle of a desert and jungle for instance). Then as I pass over the points to generate the terrain, I'd have some set params (or ranges of values) to use which would act as modifiers to the noise as the height for the point was generated.

That then leads me to your #2, which is what I think I want to try. The new terrain data would be created along the axis you are moving towards and then the old data falls away as you move off those locations... my thought there was to put the data into a memblock or bank and once its a certain size, write to a file, empty the memblock (bank) and start again. Deferred writing I guess? Reading would be done in the same manner... I'd read the block size + a few buffer segments and then keep the buffer full as the player moves, which should keep the shifts working smoothly. I'd also need to generate the extra buffer segments during the initial build of the map as well.


Thank you for the source code too.. this gives me alot to look at. I appreciate that a ton.


@Lewis999
If I can't get this matrix thing working, that may very well be the way I need to go. I can see how using memblocks (banks) gives so much more control but if one calculation is off... nothing works.


I'm still not even sure if I'm on the right track or if what I want to do will even work and be viable for something more... but I'm having fun and learning a ton along the way. Thanks to everyone for the continued input. I've gotta clean up my code quite a bit, but I'll share the matrix code I have so far later tonight. Sorry for all the rambling as well.
WLGfx
16
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 15th Apr 2012 05:26 Edited at: 15th Apr 2012 05:28
Yeah, the first idea (#1) was one I was thinking about for a while but using the simplex noise with the matrix terrains I could easily get it to update a 3x3 grid or more. ie. The middle grid could be using a 512x512 detail and the outer grid half or less. The simplex noise would only update the scrolling of them, all of them.

I've got this video renderer plugin that causing a couple of problems for me at the moment trying to make a DBP plugin out of it. It shouldn't take too much to add the extra matrix commands so I'll get back to you asap when I start making some headway and let you know.

How did you get on with the texture generation code? The one using 256 textures from a gradient image...

EDIT: There also was a sample DBP program I posted that shows real time simplex noise terrain updating just using the built in DBP commands. Smooth as anything at the moment but when I turn that into plugin functions, it will automatically update the normals too.

Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!
Joker436
12
Years of Service
User Offline
Joined: 18th Mar 2012
Location:
Posted: 16th Apr 2012 07:13
I really like idea 1 more... but I'm definitely 'not there' yet in terms of figuring out how to make it work. I can 'see' it... but I'm not there in terms of how to code it.

Yes please do let me know, I'll be glad to try it.

I did re-write the function in DBP. I have 2 concerns with what I did. One part of the function where you shifted bitwise to get the r,g and b values... the shifting thing is something I'm not good with just yet.. so I used the RGBR, RGBG and RGBB functions instead. The second is this: rr = r + ( rand() & 31 ) - 16; -- I think I may have interpreted that incorrectly.

Here's the code that I hacked together from WLGfx's C function:



I made one small change so that it returns the image ID that the get image call uses.. but otherwise I think it's working.

I reference it like this in my program:



It works too, my little terrain sandbox thing now has a texture! It uses 90MB of memory total, I was getting 93 fps.

Updating the normals automatically would save alot of processing power I would think? I got tied up this weekend and didn't get to mess around with simplex like I wanted. I'll get to that this week.
WLGfx
16
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 16th Apr 2012 20:39
Well for starters loading the png file that holds the gradient saves 90MB of space with a little function that generates the textures. But, and you're going to hate me for this too. The DBP function for the texture generation was already in the code provided in the link above in an earlier post. The bike game comes complete with all the source code. Sowwy, I forgot to mention that...

I'm made up you're getting it working too, it's always nice to hear that it's working, and it's fast enough too. I should have my video capture utility working later or tomorrow so I'll get back onto the extra functionality of the simplex noise plugin. In the plugins thread it does explain some of the optimisations I've made to speed up the simplex noise, the main one was to completely replace the 'square root' function with one that take 1/78th of the time.

Definitely the first thing to do is the add the normal calculations. That will be the first thing.

The code which might have saved you some time from the bike game:


Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 18th Apr 2012 23:33
I'm going to chime in here for a moment even though, admittedly, I haven't read the entire thread in detail; so I may be repeating some ideas that have stated.

First, for "endless terrain" it's really not necessary to have a series of linked meshes. You only need one, and you can scroll the data in and out through an array or memblock (as I believe has been mentioned). You also do not need to store huge amounts of data. The data can be calculated on the fly especially if you are using perlin noise which is virtually endless.

Second, in my opinion, a terrain size larger than 32 x 32 tiles can be overkill depending on your needs. If the vantage point is from the ground, the level of detail can be handled by textures. You don't see every cranny and crevice in the entire terrain itself. This also lends itself to fast height map generation and a super low memory footprint for the height map. Visually, you still can see a very nice terrain. And if your heightmap is super pointy/jagged you can lower the tile BY tile size and that will help smooth it out. Add a smoothing routine to the terrain itself and you can get some nice results.

I'll post a screeny of a terrain from some work on this I was doing before. I can't remember if this is a 17x17 or a 33x33 grid, at any rate, it's a rat's eye so it demonstrates what the camera is seeing as one walks about. The bumpiness is handled with textures and the shadowing by normals and light angles - nothing fancy. This was done in DarkBASIC Classic:

Enjoy your day.

Attachments

Login to view attachments
Joker436
12
Years of Service
User Offline
Joined: 18th Mar 2012
Location:
Posted: 19th Apr 2012 02:02
Hahah no worries WLGfx, I should have looked in the source first! Coding the function did teach me a few things though... didn't know a thing about locking pixels before. Good stuff!

@Latch
No worries at all! I appreciate all the input I can get! I've attached a screen of the terrain I have right now with no texture on it, after normals are calculated. This is using WLGfx's perlin noise plugin right now, and a function I hacked together that calculates the normals at the same time as I get the heights from the plugin.

It's not really an 'endlessly random' terrain that I'm after. I want the terrain to end at some point... not really end persay, just wrap back to where to started, simulating a planet.

I have 3 goals in this concept I'm dreaming about... may not be realistic, but this is what I'm looking to try:
- each 'planet' generated would be different in at least some way... name... location, climate... something.
- I'd like to generate something that at least resembles a planet in terms of what exists... bodies of water... hills, plains, mountains etc.
- I'd like to be able to save all the information about whatever is generated so that the planet could be shared with others... if for instance you played and enjoyed your 'world', you could easily share it with your buddy on a flash drive or email it to her/him or some such. Each point would be the same... I could say "check out 128,53 on the map... there's a cool blah blah blah there.".


Probably going to kick myself here, but here is the code I pieced together to do what I have there. Probably lots of wasteful code here too, so be nice. You'll need the MatrixUtil plugins from IanM and WLGfx's plugin to run the code.

Attachments

Login to view attachments
WLGfx
16
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 19th Apr 2012 02:36
@Latch - I've just started working on a few Matrix upgrades which helps with detailing the terrain and automatically calculating normals. The idea is having a reasonably large terrain but the section the camera is on (ie the centre grid) is higher detailed. There's a few difficulties I'm facing so you'll probably see some questions popping up in the forums from myself.

The main idea is so that further distances can still be visible if the game/program is not using fog but being LOD'd down. So it's up to the coder to set the grid sizes and detail levels.

I'll just see how I get on with it as I think I've started something a little bigger than what I was expecting. The main important part will be the normals calculation with just one DBP command.

Currently I'm studying the Matrix structure in DBP so I can direct access to the mesh data for an extra boost of speed.

Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 19th Apr 2012 08:45 Edited at: 19th Apr 2012 09:05
@WLGfx and @Joker

Neat Stuff!

Quote: "the main important part will be the normals calculation with just one DBP command"


You may have already thought about this but, you can get what you need right out of the height map. If each dot in your height map represents a vertex on your terrain and you know the X and Z size of a cell and you know the maximum Y height, you can calculate the normals before even rendering the terrain.

The x and z size won't change cell to cell if you are using a rectangular or square height map as the source. So you only have to get those values once.

For the Y value, you can either calculate each y height based on the maximum terrain height allowed and the value in the height map; for example:

a gray scale map may have a minimum value of 0 and a max of 255 and you terrain may have a height from 0 to 10000

ht=(gray value * 10000)/255

Or you can calculate the x and z values based on the maximum height and maximum gray value:

xhmap = (255*xtilesize)/10000
zhmap = (255*ztilesize)/10000

This is probably the way to go as you would only need to calculate them once. Then you could just use the gray value instead of calculating each y.

Then treat the dots as vertices, figure out the triangles, and calculate the normals using the cross-product. Average the face normals around a point to get the vert normals.

Does that make any sense to you? So if I had a 4 by 4 heightmap (really small!) the pixels or byte values might look like



Where I have 0, that represent 0,0 in the 2d map and 0,0,0 on a terrain. The X runs from left to right and the Z runs from bottom to top.

I go through my 2d map and grab the dots that would make up a triangle. My first triangle is



Lets say the pixel or byte value at those locations are:
100,30,127 for A,B, and C respectively.

Now, if in my terrain, each cell has an xsize of 40 and a zsize of 40, and the maximum height it can be 1000, then the values I use for my 3d verts in the crossproduct calculation is



X and Z will always be those values (if my individual cell size is 40x40) so I only need to figure them out once. Now I just use the gray value and those x and z values and my 3d verts become:



Then you find the cross product by first finding the 2 edges (vectors) of the triangle (plane)

va=C-A
vb=B-A

The normal for the face is the cross product of va and vb

For every triangle, the x and z values are either 0 or 10.2 in this example, and the only value that will change is the gray value. This will allow you to go through your height map and calculate all of your normals before rendering your terrain directly from your height map with a minimum of calculations.

If you did decide to make one huge height map of a certain size instead of generating a portion at a time, you could precalculate all of the normals ahead of time and then just pull them from memory or an array as the visible section of the terrain is drawn.

Keep in mind, the values of x and z here are derived from the future cell size and they are only used to help figure out the normals directly from the height map.

Your cell size comes from how big the x and z 3d dimensions are divided by the number of cells in each of those directions. We convert that cell size so that it is relative to the maximum gray value so our normals are correct.

Enjoy your day.
Joker436
12
Years of Service
User Offline
Joined: 18th Mar 2012
Location:
Posted: 19th Apr 2012 22:50
Thanks Latch... You and WLGfx are way, way beyond my measly skills here. I'm way out in deep water here.


It sounds as though you're saying that a heightmap is a better option than the matrix thing?
WLGfx
16
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 20th Apr 2012 00:24
Yeah, it's kinda how I figured it out not so long ago when I was playing around with openGL and my procedural level generator code. This is the snippet that calculates all the normals for every face and then averages out the vertex normals:


Most of my stuff is in C/C++ and it what I'll be using when adding the extra command to the Matrix command list. I've also had a look through DBP's source code and found that I can actually access the matrix data directly so it will be mega fast for calculating the normals. I did notice while browsing through the source code to DBP that the MATRIX UPDATE command could actually do with a little tweaking as it copies the data to a buffer, changes it, then uploads it to the main buffer. I might also update that function by adding some assembler optimisation.

It might take me a couple of days to get the commands up and running but I'm determined. As I go through some more of the source code I might update some of the other functions so long as I understand it okay'ish enough.

Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 21st Apr 2012 00:20
@Joker

Quote: "Thanks Latch... You and WLGfx are way, way beyond my measly skills here. I'm way out in deep water here.


It sounds as though you're saying that a heightmap is a better option than the matrix thing?"


I'm sorry, I was being very general. I went back through the thread in more detail and tried to "educate" myself better on what you were trying to accomplish.

When I say "heightmap" I'm talking about whatever you use to set the heights of a matrix or some other 3d grid; whether it's a gray scale bitmap, or an array of bytes or float values, or whether it's generated noise such as classical Perlin or simplex Perlin noise, etc.

So by the matrix thing do you mean you are using Perlin noise to create the heights for the matrix? The noise would be the heightmap I'm referring to.

What I was trying to say about the normals is, they can be figured out before you draw the matrix or grid. Their values can be calculated based on the values of the heightmap way before the 3D world is even touched. In your code above it looks like you are calculating the normals after the matrix is drawn - which is what one has to do most of the time when using the DB matrix commands; but even here, the normals could have been calculated during the noise generation phase and stored in a separate array or something and then simply written to the matrix along with the heights.

But what you are doing sounds like you are totally on the right track. How do you handle the biomes though?

@WLGfx
Looks good! Is this a typo? Maybe should be nx ny and nz ?



Also, I'm not as advanced as you in C++ (and not at all in assembly), so maybe I'm interpreting the code wrong. Are you averaging the face normals around a single vert that shares the same faces (one way to get the vertex normals) or are you averaging the normal by the number of verts?

Just throwing this out there: you could probably dump the normalization of the normals, or leave it as a flag to set to include or not by the user, and grab a little bit of speed. Without it, the normals will be more intense - deeper shadows, brighter highlights. If the generator is for DBPro, the normalization might be handled with SET NORMALIZATION ON. Depending on the application or environment (Direct X, OpenGL, Mesa, etc.) normals may automatically be recalculated so the flag might be useful when you need just a little bit faster processing.

Of course there is some variation of


I don't know how heavy using all those trig functions is on speed. And I don't think it accounts for the entire influence of neighboring face normals.

Quote: "Most of my stuff is in C/C++ and it what I'll be using when adding the extra command to the Matrix command list. I've also had a look through DBP's source code and found that I can actually access the matrix data directly so it will be mega fast for calculating the normals. I did notice while browsing through the source code to DBP that the MATRIX UPDATE command could actually do with a little tweaking as it copies the data to a buffer, changes it, then uploads it to the main buffer. I might also update that function by adding some assembler optimisation.

It might take me a couple of days to get the commands up and running but I'm determined. As I go through some more of the source code I might update some of the other functions so long as I understand it okay'ish enough.
"


Wow, very impressive!

Enjoy your day.
WLGfx
16
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 21st Apr 2012 03:33
@Latch - Thanks, I never spotted that and I was wondering why the terrain in my openGL procedural level generator wasn't quite looking right.

I've almost finished the "MATRIX NORMALISE matrixID" command. Just writing some test code in DBP then I'll post the update in the Simplex Noise plugin. Then it will be some work on using the simplex noise on the matrices themselves. (I'm going to have to check the Name of the function in case it clashes with anything else)

It was sometime ago I went through different ways of calculating vertex normals because terrains in DBP look sooo flat and having to calculate them manually was a nightmare and slow. I think I've seem a variation on your code Latch. I've tried something similar, but I found that writing one function to calc all faces first then smooth shared verts last is general for almost any object I create that used shared verts.

@Everyone - Hopefully by the morning a MATRIX NORMALISE function will be up and running. (It will be added to the Simplex Noise plugin because there'll be a few more functions coming for the Matrix set)

Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 21st Apr 2012 06:50
Quote: "I think I've seem a variation on your code Latch."

It's not my code, I think it's a variation of Lee Bambers matrix smotothing (vertex normal calculating code). I grabbed from jokers code further above.

Enjoy your day.
WLGfx
16
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 21st Apr 2012 13:59
I've added the normalisation of a matrix to my simplex noise plugin finally. Hoping for any bug reports (shouldn't be any, I've tested it loads). Found here -> http://forum.thegamecreators.com/?m=forum_view&t=189861&b=18

@Joker436 - You might find the sample on page 3 a tad interesting which generates a terrain, textures it according to the height value and normalises it. Hope this helps out...

Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!
Joker436
12
Years of Service
User Offline
Joined: 18th Mar 2012
Location:
Posted: 23rd Apr 2012 03:55
@Latch

No need to apologize at all. The light bulb went off... I get what you were meaning now. The calcNormal function was something I found in either a tutorial or another example from the forums... I just turned it into a function. Buuuuut... thanks to WLGfx... I don't even need that anymore! The normalizing stuff in the Simplex Noise plugin is looking really good to me.

In terms of the biomes... what I've been thinking is a weight system... each biome has a weight... player spawns at x,z, that's a center point for a biome space (highest weight for that particular biome). As the player moves in any direction, the weight decreases. When the weight gets below a threshold, new biomes are selected and the process reverses. Weight increases to its max, then decreases again to zero... and another biome is selected.

I think it should work. *fingers crossed*

@WLGfx

The simplex plugin is... not to be punny but simply amazing. I setup a little utility to modify the inputs by pressing keys and let me switch between the 2 noises (perlin and simplex)... I wanted to visualize the how the values changing impacted terrains with various sizes and point counts. I actually had to add a delay into my modification of the simplex input values because the output was so fast I couldn't stop them manually and get decent results. It's a simple little thing, if you'd like me to I'll share it over in your thread.


I'm also in the process of rebuilding my little matrix thing. That code I posted as I've found was full of holes and variables that didn't need to be there. I'll re-post that when I'm done with it.

Back to coding for me... thank you to you both... I really appreciate the continued input and suggestions.
WLGfx
16
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 23rd Apr 2012 15:34
@Joker436 - I'd like to see what you've come up with using the simplex plugin. I'm finding it interesting all the time when people find a use for it. Excellent stuff. I'm just adding a replacement perlin noise and then might work on the diamond square algorithm too.

My problem is I get carried away with so many projects, so far so good that they're small projects...

Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!
seppgirty
FPSC Developer
14
Years of Service
User Offline
Joined: 3rd Jul 2009
Location: pittsburgh, pa.
Posted: 23rd Apr 2012 19:00
hey guys, here is a link to a free height map generator program

http://www.reinerstilesets.de/programme/hemahema/

i always wondered how well it would work with DBP. i find the texture maps feature very nice.

gamer, lover, filmmaker
Joker436
12
Years of Service
User Offline
Joined: 18th Mar 2012
Location:
Posted: 7th May 2012 17:09
Hi again all,

I've attached a zip file containing some screen shots from my program. I've finally had some success with my matrix project. Using WLGfx's Perlin Noise plugin, I'm able to create a very large space of noise and grab only a 128x128 portion of it like this:



Moving is a challenge, and that's where I'm stuck. I have things working in absolute direction (up down left right) movement... the terrain is seamless and reads the heights from the 'noise space' that I used here (replaced variables with real #s):



Screenshots reflect this... upmovement.png / downmovement.png.

You can see the issue I'm having in badmovement.png... it's the diagonal movement that seems to be the problem. That's what it looks like when I update the "0" point on that axis.

In trying to figure out why I'm having this problem, I did get some 'better' results by updating the 'last' point in the matrix and then letting it shift into view. That's in bettermovement.png

Buuuut... even in bettermovement.png, a seam still rolls in from the corner. The noise positions that get used look correct as I move about... but I still get the seam. I've tried adding/subtracting values thinking I was off by one or more on either the noise or which matrix point to update, but nothing seems to resolve it. In the final screen, longtermmovement.png you can see the seam that rolled in as I moved about.

I'm definitely scratching my head. Is there something that I'm just missing?

Attachments

Login to view attachments
WLGfx
16
Years of Service
User Offline
Joined: 1st Nov 2007
Location: NW United Kingdom
Posted: 7th May 2012 18:04
It looks to me a possibility of a few things.

When I've used the seamless tiling, I tend to setup the matrix as a whole, but either way that shouldn't matter. The seamless tiling usually fits 0 to wid/hgt matrix. Any X and Y (or Z) values passed to the noise function will be wrapped if they go over the bounds of the set width and height. Similar to 'xnew = fmod( oldx, width )'.

I've noticed that setting up a matrix the grids go from 0 to width/height. When I was playing around I found this out quick. I was setting up a matrix of 256x256 but was setting the heights 0-255 when I noticed the horizontal and vertical seams. By the look of your code snipped though, you've accounted for this.

The tiling calculation ought to return a value between -1 and +1, but I don't think it actually does. I'll double check the code when I get back to see if it's correctly done. My test snippets at the time had to account for odd ranges in some of the perlin noise functions.

Updating the noise on the fly is better recommended using the simplex noise (which I have in mind an update for). The origial PNoise plugin is the most accurate but the slowest. And I'm hoping to add a lot more functionality in the SNoise simplex and perlin code, such as seamless noise

Using the scroll matrix functions and then adding the WL Matrix Normalise function will still work.

Anyway, I'm back late tomorrow afternoon from my 5 day break away so I'll have a better look into it then for you if you've got any code snippets. The diagonal glitches in the images at this moment are confusing me but I'm sure there's an easy way around it.

Hey, fingers crossed...

Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!
Joker436
12
Years of Service
User Offline
Joined: 18th Mar 2012
Location:
Posted: 7th May 2012 21:17 Edited at: 8th May 2012 07:25
@WLGfx,

I played around with things some more. I found that if I'm moving in an absolute left direction, I need to update the zero point... if I'm moving diagonally... I update the last point and allow it to shift in. Very strange behavior, but I coded for it.

I stuck to the original perlin for now because I wasn't sure if the tiling/wrapping I want would work correctly with simplex. You'll notice that I use your normalizing function in this code - it works like a charm.

Here's the code for the whole thing. Please excuse any commented out references to functions that don't exist. You'll notice real and integer values for the same thing... I was originally thinking that I was losing precision using integers and that would be the cause of the problem... that did not pan out, and I haven't removed the code yet.

Hold down the 2,3 or 4 key change the view of the camera. The 4 key moves the camera to the area on the matrix where I believe the problem starts.

Numpad 8 rotates you to zero degress, 4 to 270, 2 to 180 and 6 to 90.. so you can look at absolute direction. Arrow keys control direction.



EDIT:
@WLGfx,

I tested on a 128x128 set of perlin values from the original dll, and never once got a value outside of the range. I saved the values as a text file if you'd like me to upload it?

I also updated the code again. I had some values reversed.. but that didn't change things.

Login to post a reply

Server time is: 2024-05-17 06:34:01
Your offset time is: 2024-05-17 06:34:01