# normal calculation

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

## Recommended Posts

could someone please write me a function to calculate normals of a mesh... the function should use the value of float WaterHeight[x][y] and calculate the normals into the field float WaterNormal[x1][y1][z1][x][y] (yea i know its a bit wierd but i dont want to use vectors... i have my reasons...) thx...

##### Share on other sites
Since it looks like you are calculating normals for planar mesh (water/terrain) this thread will help you.

If you are thinking about general meshes then tell us and we'll give you more specific answer.

PS: And you better have very good reasons for using WaterNormal[x1][y1][z1][x][y]. You probably know it requires 4 multiplications and 4 additions to get a single value from that, right?

##### Share on other sites
In this thread I posted some code which has a routine I use for water - but it uses vectors. It's very straightforward, so you might be able to convert it to the calc above.

hth
F451

##### Share on other sites
lol i dont understand either of those... thats the reason id like to have an alrdy finished function that uses float HeightMap[x][z] and calculates CVECTOR NormalMap[x][z].. ive programmed all the vector operators but not the crossproduct...

if somebopdy could do this for me id be very thankful... shouldnt take much time jsut reprogram some function uve alrdy got..

##### Share on other sites
Quote:
 Original post by Anonymous Posterlol i dont understand either of those... thats the reason id like to have an alrdy finished function that uses float HeightMap[x][z] and calculates CVECTOR NormalMap[x][z]..

People will generally not just give you the code in the form you need. First you have to show that you did put some work in it. The links posted above or a quick google search would give you more than you need to implement it yourself.

Quote:
 Original post by Anonymous Posterive programmed all the vector operators but not the crossproduct...

a) Generating terrain/water normals does not require cross product.
b) You should be able to write it yourself in 5 min with a help of math book/Google/open-source projects/.. if you actualy need it.

##### Share on other sites
well the reason i want somebody else to write it is because i cant get it to work myself... here is my code if u can find whats wrong id apprecieate that also...

void CTERRAIN::SetUpNormals(int a)
{

// m_fVec[0]= x;
// m_fVec[1]= y;
// m_fVec[2]= z;

CVECT0R HeightMap[128][128];

for (int z = 0; z 0 && z 0 && x 0 && z 0 && x <

##### Share on other sites
void CTERRAIN::SetUpNormals(int a)
{

// m_fVec[0]= x;
// m_fVec[1]= y;
// m_fVec[2]= z;

CVECT0R HeightMap[128][128];

for (int z = 0; z < 128; z++){
for (int x = 0; x < 128; x++){
HeightMap[z][x][a].m_fVec[0] = x;
HeightMap[z][x][a].m_fVec[1] = GetWaterHeight(x, z, a);
HeightMap[z][x][a].m_fVec[2] = z;
}
}

CVECTOR v1,v2,v3,v4,v5,v6;
CVECTOR n,n1,n2,n3,n4,n5,n6;

for (int z = 0; z < 128; z++ ) {
for (int x = 0; x < 128; x++ ) {
if ( z == 0 && x == 0 ) {
// back left corner - 1 tri 2 vertices
v1 = HeightMap[z+1][x] - HeightMap[z][x];
v2 = HeightMap[z][x+1] - HeightMap[z][x];

n = Cross(v1,v2);

} else if ( (z > 0 && z < (128-1)) && x == 0 ) {
// left edge - 3 tri 4 vertices
v1 = HeightMap[z][x+1] - HeightMap[z][x];
v2 = HeightMap[z-1][x+1] - HeightMap[z][x];
v3 = HeightMap[z-1][x] - HeightMap[z][x];
v4 = HeightMap[z][x+1] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);
n3 = Cross(v3,v4);

n = (n1+n2+n3)/3.0f;

} else if ( z == (128-1) && x == 0 ) {
// front left corner - 2 tri 3 vertices
v1 = HeightMap[z][x+1] - HeightMap[z][x];
v2 = HeightMap[z-1][x+1] - HeightMap[z][x];
v3 = HeightMap[z-1][x] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);

n = (n1+n2)/2.0f;

} else if ( z == (128-1) && (x > 0 && x < (128-1)) ) {
// front edge - 3 tri 4 vertices
v1 = HeightMap[z][x+1] - HeightMap[z][x];
v2 = HeightMap[z-1][x+1] - HeightMap[z][x];
v3 = HeightMap[z-1][x] - HeightMap[z][x];
v4 = HeightMap[z][x-1] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);
n3 = Cross(v3,v4);

n = (n1+n2+n3)/3.0f;

} else if ( z == (128-1) && x == (128-1) ) {
// front right corner - 1 tri 2 vertices
v1 = HeightMap[z-1][x] - HeightMap[z][x];
v2 = HeightMap[z][x-1] - HeightMap[z][x];

n1 = Cross(v1,v2);

n = n1;

} else if ( ( z > 0 && z < (128-1)) && x == (128-1) ) {
// right edge - 3 tri 4 vertices
v1 = HeightMap[z-1][x] - HeightMap[z][x];
v2 = HeightMap[z][x-1] - HeightMap[z][x];
v3 = HeightMap[z+1][x-1] - HeightMap[z][x];
v4 = HeightMap[z+1][x] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);
n3 = Cross(v3,v4);

n = (n1+n2+n3)/3.0f;

} else if ( z == 0 && x == (128-1) ) {
// back right corner - 2 tri 3 vertices
v1 = HeightMap[z][x-1] - HeightMap[z][x];
v2 = HeightMap[z+1][x-1] - HeightMap[z][x-1];
v3 = HeightMap[z+1][x-1] - HeightMap[z][x];
v4 = HeightMap[z+1][x] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v3,v4);

n = (n1+n2)/2.0f;

} else if ( z == 0 && ( x > 0 && x < (128-1)) ) {
// back edge - 3 tri 4 vertices
v1 = HeightMap[z][x-1] - HeightMap[z][x];
v2 = HeightMap[z+1][x-1] - HeightMap[z][x];
v3 = HeightMap[z+1][x] - HeightMap[z][x];
v4 = HeightMap[z][x+1] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);
n3 = Cross(v3,v4);

n = (n1+n2+n3)/3.0f;

} else {
// internal - 6 tri 6 vertices
v1 = HeightMap[z][x+1] - HeightMap[z][x];
v2 = HeightMap[z-1][x+1] - HeightMap[z][x];
v3 = HeightMap[z-1][x] - HeightMap[z][x];
v4 = HeightMap[z][x-1] - HeightMap[z][x];
v5 = HeightMap[z+1][x-1] - HeightMap[z][x];
v6 = HeightMap[z+1][x] - HeightMap[z][x];

n1 = Cross(v1,v2);
n2 = Cross(v2,v3);
n3 = Cross(v3,v4);
n4 = Cross(v4,v5);
n5 = Cross(v5,v6);
n6 = Cross(v6,v1);

n = (n1+n2+n3+n4+n5+n6)/6.0f;

}
Normalize(n);

/*inline void SetNormal(int x, int z, int a, float x1, float y1, float z1){

//CVECTOR NormalMap[128][128][128];
// m_fVec[0]= x;
// m_fVec[1]= y;
// m_fVec[2]= z;

NormalMap[x][y][a].m_fVec[0] = x1;
NormalMap[x][y][a].m_fVec[1] = y1;
NormalMap[x][y][a].m_fVec[2] = z1;
}
*/

SetNormal(x, z , a, n.m_fVec[0], n.m_fVec[1], n.m_fVec[2]);
}
}
}

CVECTOR CTERRAIN::Cross(const CVECTOR &vec1, const CVECTOR &vec2){

// m_fVec[0]= x;
// m_fVec[1]= y;
// m_fVec[2]= z;

return CVECTOR(vec1.m_fVec[1] * vec2.m_fVec[2] - vec1.m_fVec[2] * vec2.m_fVec[1],
vec1.m_fVec[2] * vec2.m_fVec[0] - vec1.m_fVec[0] * vec2.m_fVec[2],
vec1.m_fVec[0] * vec2.m_fVec[1] - vec1.m_fVec[1] * vec2.m_fVec[0],);
}

void CTERRAIN::Normalize(CVECTOR &vec){

// m_fVec[0]= x;
// m_fVec[1]= y;
// m_fVec[2]= z;

CVECTOR temp = vec;

float mag = sqrtf(temp.m_fVec[0] * temp.m_fVec[0] + temp.m_fVec[1] * temp.m_fVec[1] + temp.m_fVec[2] * temp.m_fVec[2]);

vec.m_fVec[0] = temp.m_fVec[0] / mag;
vec.m_fVec[1] = temp.m_fVec[1] / mag;
vec.m_fVec[2] = temp.m_fVec[2] / mag;
}

##### Share on other sites
it seems to be working now (the program starts..) ... but then the next question how do i add lighting to it? right now it looks just like a flat surface although there are waves...

##### Share on other sites
It seems like you are doing much more than just calculating normals in your SetNormals() routine. You should keep this routine down to just the job of traversing your heightmap and calculating and setting the normals per vertex, and not doing all of things like defining and initialising the heightmap.

Your problem of your surface being flat might be because you pass a value into your SetNormals routine, define yourheightmap (which, btw, exists only for the life of the routine and gets automatically destroyed when the routine ends), **set all vertices in your heightmap to the value passed in**, and then calculate the same normal value for each vertex (since all are the same height). If you are repeatedly calling this routine from inside the rendering code, then you could be potentially setting the heightmap to one value over and over again.

The normal calcs you are using are fine for a one-time setup of a static terrain. Do the terrain initialisation and normal calculation *before* the render routine (ie. in the InitGL() routine). Also, I wouldn't use this lengthy normal calculations for a water mesh. It's prohibitively expensive. Water needs to have the normals calculated every frame (execution of the render routine essentially). For that you should use something more optimised and/or a shortcut method that approximates the normals. I gave an example of one of those routines in the link I provided earlier. It was something like 10 lines long - compared to the 50+ lines of the static mesh routine.

hth
F451

##### Share on other sites
the temporary heightmap in the routine retrives the values from the "real" heightmap.. i had to do this since the normal calculations uses another "form" of heightmap... soo the heightmap during rendering is still there...

all my waves are precalculated using perlin noise and some of my simple mods in a 3d array WaterHeight[x][z][a]... where i change the a after every rendering... it gives a long initialization but fast rendering...

and about those 10 lines... im clueless of how to use them...

but it looks like this problem wont be solved unless u see all the code which would be to much to post here... thx anyways..

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

(You must login to your GameDev.net account.)

• 10
• 11
• 13
• 9
• 11
• ### Forum Statistics

• Total Topics
634092
• Total Posts
3015448
×