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


random hills on surfaces ??

Recommended Posts

So, you want to generate a realistic-looking mountains?
If so, there''s an algorithm lying around somewhere. I''ve seen it before. Too bad I can''t remember the name and it doesn''t appear very often. But such algorithm is exist.
I''ll tell you when I found it.

Share this post

Link to post
Share on other sites
If you wanna do this procedurally (ie at runtime, and with a certain amount of randomness), then try using a 2D Perlin noise function. Loop through your vertices, calling your noise function with the x and z coords (if your landscape is across the y plane), and deform each point by the amount returned from the function.

For example, try this Perlin noise function (apologies to the author, can''t find the details anyway but I can''t take credit):

#define PERLIN_SIZE 1024
#define PERLIN_RND ((float)(2.0f*(float)rand()/(float)RAND_MAX)-1.0f)
#define PERLIN_NORM(X) {float l = (float)sqrt(X.x*X.x+X.y*X.y);X.x/=l;X.y/=l;}

struct Vector2f{
float x, y;

Vector2f perlinField[PERLIN_SIZE][PERLIN_SIZE];

void InitPerlinField(int m_scale);
void GetPerlinNoiseValue (float x, float y, GLfloat *result);
int scale;

void InitPerlinField(int m_scale) {
scale = m_scale;
if (scale>128) scale=128;
if (scale<0) scale=0;

for(int y=0; y<PERLIN_SIZE; y++) {
for(int x=0; x<PERLIN_SIZE; x++) {
perlinField[x][y].x = PERLIN_RND;
perlinField[x][y].y = PERLIN_RND;

for(int i=0; i<scale; i++) { // Force repeat

perlinField[scale][i] = perlinField[0][i];
perlinField[i][scale] = perlinField[i][0];

perlinField[scale][scale] = perlinField[scale][i] = perlinField[i][scale] = perlinField[0][0];

void GetPerlinNoiseValue (float x, float y, GLfloat *result) {
// Scale the input!!


/* Calculate the index of the list */
int x1, y1, x2, y2;
x1 = (int)x*scale/PERLIN_SIZE;
x2 = x1 + 1;
y1 = (int)y*scale/PERLIN_SIZE;
y2 = y1 + 1;

Vector2f pos;
pos.x = (float)x*(float)scale/(PERLIN_SIZE);
pos.y = (float)y*(float)scale/(PERLIN_SIZE);

/* Calculate the vector from the grid corner to the point */

Vector2f vect[2][2];
vect[0][0].x = pos.x - x1;
vect[0][0].y = pos.y - y1;

vect[0][1].x = pos.x - x1;
vect[0][1].y = pos.y - y2;

vect[1][0].x = pos.x - x2;
vect[1][0].y = pos.y - y1;

vect[1][1].x = pos.x - x2;
vect[1][1].y = pos.y - y2;

float s, t, u, v;
s = perlinField[x1][y1].x*vect[0][0].x + perlinField[x1][y1].y*vect[0][0].y;
t = perlinField[x2][y1].x*vect[1][0].x + perlinField[x2][y1].y*vect[1][0].y;
u = perlinField[x1][y2].x*vect[0][1].x + perlinField[x1][y2].y*vect[0][1].y;
v = perlinField[x2][y2].x*vect[1][1].x + perlinField[x2][y2].y*vect[1][1].y;

float Sx = 3*(pos.x-x1)*(pos.x-x1)-2*(pos.x-x1)*(pos.x-x1)*(pos.x-x1);
float a = s + Sx*(t-s);
float b = u + Sx*(v-u);

float Sy = 3*(pos.y-y1)*(pos.y-y1)-2*(pos.y-y1)*(pos.y-y1)*(pos.y-y1);

*result = a + Sy*(b-a);
*result = (*result)*0.5f+0.5f;

And you could use it like this:

GLfloat modifier;

for (int x=0; x<LANDSCAPE_XSIZE; x++) {
for (int z=0; z<LANDSCAPE_ZSIZE; z++) {
GetPerlinNoiseValue ((float)x, (float)z, &modifier);
// Now you need to deform the point (x, z) on your landscape

// by multiplying the y coord of this point with modifier

// (or you can try adding it).


// How you do this depends on how you''re storing your

// landscape verts - buts an example:

landscape[x][z] *= modifier;

Note that you don''t need to do this every frame! Do it once at the start of your program.

Also, note that for a given input the noise function will always give the same output, so you can use GetPerlinNoiseValue again if you need to determine the height at a given (x, z) on your landscape - for example to find out where to place a character.


PS The noise functions take an (x, y) coordinate - but don''t be confused between these and the (x, y) coords in your world; the Perlin''s x and y refer to its internal 2D grid, which you''re mapping onto (x, z).
code, pics, life

Share this post

Link to post
Share on other sites

thx for all the help. My Idea was almost like the Perlin noise function, but I didn''t have any idea how to relize it.
Now I know how to do it but how do I do it with already deformed surfaces. How can I loop trough vertices of a surface.

big thx


Share this post

Link to post
Share on other sites
When you say already deformed surfaces - are you using a heightmap and want to add a little detail? Or something else?

Can you post some code of your setup routines so I can see how you should loop through your verts?
code, pics, life

Share this post

Link to post
Share on other sites

I use normal surfaces::

float hill_01[3][3][3] = {

U can do alot of neat things with that but without bumps it just doesn''t look real


Share this post

Link to post
Share on other sites
Ah, I see. First you''re going to need lots more polys!

Try making a grid of 50x50 or so...

GLfloat hill_01[50][50][3];
GLfloat height;


for (int i=0; i<50; i++) {
for (int j=0; j<50; j++) {
GetPerlinNoise(i, j, &height);

hill_01[i][j][0] = (float)i-25.0f; // x coord

hill_01[i][j][1] = height; // y coord

hill_01[i][j][2] = (float)j-25.0f; // z coord


Share this post

Link to post
Share on other sites