#### Archived

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

# 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 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 on other sites
arkansas    122
I wanna modify the geometry.

arkansas

##### 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 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 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 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 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 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  }}