Jump to content


Heightmap vertex normals


2 replies to this topic

#1 caesar4

    New Member

  • Members
  • Pip
  • 9 posts

Posted 23 September 2004 - 11:29 PM

When you load a heightmap in your game, some of you would want to be able to light it, but in order to have lighting, you must also have the vertex normals.
This method is simple, works by averaging the normals of all adjacent triangle normals

Vertex declaration I'm using
typedef struct _SVNormVertexIColor{
	CVector vecPosition;
	CVector vecNormal;
	unsigned int uiColor;
	static const unsigned int FVF;
}SVNormVertexIColor;
const unsigned int _SVNormVertexIColor::FVF = (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE);

Normal calualation code:
// we have 'w'-width and 'h'-lenght of the heightmap

// i am assuming that you have already read all the vertices into a linear vertex buffer, with the normal vector set to 0.f

int _h = h-1;
int _w = w-1;

// cycle through each row
for(int i = 0; i < _h; i++){
 // cycle through each column
 for(int j = 0; j < _w; j++){
  CVector p1,p2,p3,v1,v2,tmp;
  int v[4];
  // calculate the positions int the vertex buffer of the adjacent vertices
  // v[0] is current vertex
  v[0] = i*h+j;	v[1] = i*h+j+1;
  v[2] = (i+1)*h+j;	v[3] = (i+1)*h+j+1;

  // store the positions of first triangle into 3 usable vertices
  p1 = this->vertices[v[0]].vecPosition;
  p2 = this->vertices[v[3]].vecPosition;
  p3 = this->vertices[v[2]].vecPosition;

  // calculate the triangle sides
  v1 = p2 - p1;v2 = p3 - p1;

  // calculate normal
  tmp = v1.Cross(v2);
  // add normal to the normal of all the vertices in the triangle
  this->vertices[v[0]].vecNormal+= tmp;
  this->vertices[v[3]].vecNormal+= tmp;
  this->vertices[v[2]].vecNormal+= tmp;
 
  // store the positions of second triangle into 3 usable vertices
  p1 = this->vertices[v[1]].vecPosition;
  p2 = this->vertices[v[3]].vecPosition;
  p3 = this->vertices[v[0]].vecPosition;

  // calculate the triangle sides
  v1 = p2 - p1;v2 = p3 - p1;
  // calculate normal
  tmp = v1.Cross(v2);
  // add normal to the normal of all the vertices in the triangle
  this->vertices[v[1]].vecNormal+= tmp;
  this->vertices[v[3]].vecNormal+= tmp;
  this->vertices[v[0]].vecNormal+= tmp;
 }
}

// normalize all vertices
for(i = 0; i<this->iVertCount; i++)
 this->vertices[i].vecNormal.Normalize();



#2 Mihail121

    Senior Member

  • Members
  • PipPipPipPip
  • 1059 posts

Posted 24 September 2004 - 06:07 AM

Ok i don't want to be rude but this is the third normal-calculating sample in a month!!!

#3 caesar4

    New Member

  • Members
  • Pip
  • 9 posts

Posted 01 October 2004 - 03:20 AM

Mihail121 said:

Ok i don't want to be rude but this is the third normal-calculating sample in a month!!!

View Post

Sure, but none of the other samples included acurate calculations, theyll just take the normal of a triangle, give it to its 3 vertices, and move on to the next triangle
this sample averages the normals of the adjacent triangles (which is partly wy it runs a little slow) and provides more accurate data, for lighting





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users