Archived

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

What's wrong with my terrain algorithm?

This topic is 4942 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hiya, First, I decided to stick this in the math forum because I''m geussing my problem is related primarly to either the method in which I sample my heightmap or the algorithms I use to generate my normals. My problem is that my terrain looks quite crappy. I don''t like the little bumps and whatnot, I''d much rather it be smooth. My terrain is a 100x100 grid containing 10,000 vertices and uses an index buffer to specify the order in which the vertices connect to form the faces. The screenshot should be enough to show what I don''t like about this, but if you want a little closer view, I''ve put the executable where you can roam around a bit up here. I suppose I''ll start by posting some code, os here we go. Here''s the code that samples the heights from a bitmap, then generates the vertices and indices. (Note, the variable dchm in my GetPixel call is a device context in which my heightmap image has been selected into)
int vertexnum=0;
	int indexnum=0;
	for(int z=0; z<100; z++)
	{
		for(int x=0; x<100; x++)
		{
			Vertices[vertexnum].position=D3DXVECTOR3(x*5-250,GetRValue(GetPixel(dchm,x,z))-150,z*5-250); // GetRValue(GetPixel(dchm,x,z))


			
			// Generate some Indices

			if(x!=99) // take out some uglyness...

			{
			Indices[indexnum]   = vertexnum; 
			Indices[indexnum+1] = 100*(z+1)+x;
			Indices[indexnum+2] = 100*(z+1)+(x+1);
			Indices[indexnum+3] = 100*(z+1)+(x+1);
			Indices[indexnum+4] = 100*z+(x+1);
			Indices[indexnum+5] = vertexnum;
			
			indexnum+=6;
			}
			vertexnum++;
			
		}
	}
Here''s how I generate the normals
for(int zz=0; zz<100; zz++)
	{
		for(int xx=0; xx<100; xx++)
		{
			// Generate Normals

			D3DXVECTOR3 vlminusv, vtminusv, vtrminusv, vrminusv;
			D3DXVec3Subtract(&vlminusv,&Vertices[100*zz+(xx-1)].position,&Vertices[100*zz+xx].position);
			D3DXVec3Subtract(&vtminusv,&Vertices[100*(zz+1)+xx].position,&Vertices[100*zz+xx].position);
			D3DXVec3Subtract(&vtrminusv,&Vertices[100*(zz+1)+(xx+1)].position,&Vertices[100*zz+xx].position);
			D3DXVec3Subtract(&vrminusv,&Vertices[100*zz+(xx+1)].position,&Vertices[100*zz+xx].position);

			D3DXVECTOR3 vnormalun;
			D3DXVECTOR3 vnormal;
			D3DXVECTOR3 temp;
			// OMFG Big Math!

			D3DXVec3Add(&vnormalun,D3DXVec3Cross(&temp,&vlminusv,&vtminusv),D3DXVec3Add(&temp,D3DXVec3Cross(&temp,&vtminusv,&vtrminusv),D3DXVec3Cross(&temp,&vtrminusv,&vrminusv)));
			D3DXVec3Normalize(&vnormal,&vnormalun);
			Vertices[100*zz+xx].normal=vnormal;
		}
	}
Any ideas on how I could make my terrain appear smoother? Thanks and Best Regards, Matt Carpenter

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Standard guess: too little precision for height as compared to how dense the grid is. Increase height precision (use float/double), apply blur filter (to get rid of jaggies in the original image), enjoy (just because).

Share this post


Link to post
Share on other sites
Hmm, well I''ve blured it quite a bit, but I don''t think I''d be able to change the precision because the height values are integers (0-255, taken from the heightmap) and I couldn''t really change the precision.. unless I should try averaging points?

Share this post


Link to post
Share on other sites
Are you using standard Gouraud/smooth shading to render the triangles? Keep in mind that this standard shading technique will artificially show bright/dark spots due to linear interpolation of color across the triangle. This might be waht you''re seeing (though the screen shot doesn''t look exactly like this artifact.) A per-pixel shading technique would look much nicer.

Graham Rhodes
Principal Scientist
Applied Research Associates, Inc.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Xtremehobo
Hmm, well I''ve blured it quite a bit, but I don''t think I''d be able to change the precision because the height values are integers (0-255, taken from the heightmap) and I couldn''t really change the precision.. unless I should try averaging points?
Load the picture, convert the heights to floats (0.0f, 1.0f, ..., 255.0f) and then blur it in the program by taking a (weighted) average of nearby points. Like this:

p[y][x] = 1.0/6.0 * (2*p[y][x] + p[y][x-1] + p[y][x+1] + p[y+1][x] + p[y-1][x]);

(yeah the blur pattern could be better)

Share this post


Link to post
Share on other sites
On your Normal code:

you use verts:
z,x-1
z+1,x
z+1,x+1
z,x+1
..
for a square heightmap, just use:
z,x-1
z+1,x
z,x+1
z-1,x
...

This is what you currently see for the same basic structure from 2 different directions:


[edited by - PyroSA on June 1, 2004 7:12:09 PM]

Share this post


Link to post
Share on other sites