Archived

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

arkansas

random hills on surfaces ??

Recommended Posts

arkansas    122
Hey I made a landscape with lots of surfaces. Some of them are like little mountains. I wanna put bumps on there do it looks real. How do I do that? thx arkansas

Share this post


Link to post
Share on other sites
_DarkWIng_    602
Do you want to add bumps like in actualy modifying your geometry or just like bumpmap?

You should never let your fears become the boundaries of your dreams.

Share this post


Link to post
Share on other sites
varokasp    122
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
IainC    127
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;
PERLIN_NORM(perlinField[x][y]);
}
}

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!!

x=(float)((int)(x*PERLIN_SIZE));
y=(float)((int)(y*PERLIN_SIZE));

/* 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:


  
InitPerlinField(4);
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.

HTH...
I.

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).

www.coldcity.com
code, pics, life

Share this post


Link to post
Share on other sites
arkansas    122
Hey

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

arkansas

Share this post


Link to post
Share on other sites
IainC    127
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?

www.coldcity.com
code, pics, life

Share this post


Link to post
Share on other sites
arkansas    122
Ok

I use normal surfaces::

float hill_01[3][3][3] = {
{{-30.0,4.0,10.0},{-60.0,6.0,25.0},{-5.0,2.0,40.0}},
{{-40.0,10.0,10.0},{-60.0,10.0,25.0},{-15.0,2.0,40.0}},
{{-50.0,4.0,10.0},{-50.0,6.0,25.0},{-50.0,2.0,40.0}}
};

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

arkansas

Share this post


Link to post
Share on other sites
IainC    127
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;

InitPerlinField(4);

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