1. ## Normal Generation Trouble.

Today I came up with an algorith for generating normals. It works fine for like a single surface and all. I then tried to apply it to my terrain generator to get lighting. But the results are not good and the terrain does not look like its lit at all. Here is the important code:

struct normals{
float x, y, z;
};
typedef struct normals normals;
normals normal[TERRAINWIDTH*TERRAINLENGTH];

...

void calculate_normal(int normal_number, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3){
float vec1_x, vec1_y, vec1_z, vec2_x, vec2_y, vec2_z;
float bigx, bigy, bigz;

vec1_x = x2 - x1;
vec1_y = y2 - y1;
vec1_z = z2 - z1;
vec2_x = x3 - x1;
vec2_y = y3 - y1;
vec2_z = z3 - z1;

bigx = (vec1_y*vec2_z) - (vec1_z*vec2_y);
bigy = (vec1_z*vec2_x) - (vec1_x*vec2_z);
bigz = (vec1_x*vec2_y) - (vec1_y*vec2_x);

normal[normal_number].x = bigx/sqrt(bigx*bigx + bigy*bigy + bigz*bigz);
normal[normal_number].y = bigy/sqrt(bigx*bigx + bigy*bigy + bigz*bigz);
normal[normal_number].z = bigz/sqrt(bigx*bigx + bigy*bigy + bigz*bigz);

normal[normal_number].x = abs(normal[normal_number].x);
normal[normal_number].y = abs(normal[normal_number].y);
normal[normal_number].z = abs(normal[normal_number].z);
}

void renderScene(void){
float height;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[0]);
glRotatef(angle, 0.0, 1.0, 0.0);
glRotatef(25, 1.0, 0.0, 0.0);
glTranslatef(-4.0, -2.0, zoom);
glColor3f(1.0, 1.0, 1.0);
for(mapx = 0; mapx < TERRAIN_LENGTH-1; mapx++){
for(mapz = 0; mapz < TERRAIN_WIDTH-1; mapz++){
glBegin(GL_TRIANGLE_STRIP);
calculate_normal((mapx*99)+mapz, mapx/DETAIL, height, mapz/DETAIL, mapx/DETAIL, height, (mapz+1)/DETAIL, (mapx+1)/DETAIL, height, mapz/DETAIL);
glNormal3f(normal[(mapx*99)+mapz].x, normal[(mapx*99)+mapz].y, normal[(mapx*99)+mapz].z);
height = map[mapx][mapz];
glTexCoord2f(0.0, 0.0);
glVertex3f(mapx/DETAIL, height, mapz/DETAIL);
height = map[mapx][mapz+1];
glTexCoord2f(0.0, 1.0);
glVertex3f(mapx/DETAIL, height, (mapz + 1)/DETAIL);
height = map[mapx+1][mapz];
glTexCoord2f(1.0, 0.0);
glVertex3f((mapx+1)/DETAIL, height, mapz/DETAIL);
height = map[mapx+1][mapz+1];
glTexCoord2f(1.0, 1.0);
glVertex3f((mapx+1)/DETAIL, height, (mapz+1)/DETAIL);
glEnd();
}
}
glPopMatrix();
glutSwapBuffers();
}

I just made the normal algorithm today so it might not be the "proper' or standard way to calculate normals but it works for a single polygon... Please help, thanks.

2. ## Re: Normal Generation Trouble.

The abs( ... ) look strange. Try to leave them out. Normals may have positive and negative components as any other vector may have. The only thing is that they have to be unit (length 1).
You can do this like this:

vector* 1/ |vector| = unit vector
since 1/|vector| is constant over all three components, you can calculate it just once.

3. ## Re: Normal Generation Trouble.

Well, I removed the abs but the results are still exactly the same. Also, the following lines normalise the vectors:
normal[normal_number].x = bigx/sqrt(bigx*bigx + bigy*bigy + bigz*bigz);
normal[normal_number].y = bigy/sqrt(bigx*bigx + bigy*bigy + bigz*bigz);
normal[normal_number].z = bigz/sqrt(bigx*bigx + bigy*bigy + bigz*bigz);

Any other ideas why it doesnt work??

4. ## Re: Normal Generation Trouble.

Maybe your normals are reversed, try reversing the order of the crossproduct of the edge vectors, use (vec2 x vec1) instead of (vec1 x vec2) like you do now. Also consider the fact that it might not be your normals that are incorrect, it might be something stupid like forgetting to set a material or enabling color material. If everything shows up white thats probably your problem since you set the current colour to white above the rendering loop.

5. ## Re: Normal Generation Trouble.

Hmmmm...

I see you have an 2D array of normals and iterate though it step by step.

The problem is your code is calculating only a normal for the given triangle and not the normal for the vertex (you need to average all triangle normals that share a given point).

I can find a that you assign the variable "Normal_number" a meaningfull value (it will be allways zero right?)

Hope that help.

LG

6. ## Re: Normal Generation Trouble.

At this moment I dont want per-vertex lighting so that I only assign a normal to each surface not to each vertex. But the results still do not look like the scene is properly lighted. If anyone is willing to look at the whole source code I can send the whole source code to look at.

7. ## Re: Normal Generation Trouble.

I dont mind having a look at it.
You'll find my email address in the profile.

Regards,

LG

8. ## Re: Normal Generation Trouble.

Say that I'm an idiot, but can you do reasonable flat shading in a triangle strip?

9. ## Re: Normal Generation Trouble.

Try replacing GL_TRIANGLE_STRIP with GL_TRIANGLES. Well probably I don't get your algo correctly...

10. ## Re: Normal Generation Trouble.

As I see from your code snippet, you try to combine a grid of quads to a surface. I every loop iteration but the first, you are creating 4 triangles. Try using GL_QUADS in the glBegin statement.
The line where you calculate the normal, you are using the same height for all three vertices, so that should produce a vector that is 0,1,0 in your representation. This may produce the lighting error you see (every surface will be lit the same way!)

Page 1 of 2 12 Last

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•