Incorrect Normals, or something

Started by
8 comments, last by Kris2456 19 years, 7 months ago
Here is a screenshot of my terrain engine. Looks crap, dosn't it? As you can see, the lighting isnt very good. The normals are calculated per vertex. When you move the spotlight around, the terrain, instead of smoothly changing, goes very blocky. It looks light each square can only be lit up, or not lit up. It dosnt make it look very good. Here is the code for my terrain:

void CIrisTerrain::CalculateNormalMap()
{
    int X, Y;
    int x,y,z;
    CVector3 normal,v1,v2,v3,v4;
    CVector3 pos[3];
    CVector3 *PolyMap = new CVector3[1023*1023];
    if(PolyMap==NULL){
        IrisLogger.Write("Something planked up with the memory");
        return;
    }
    
    //Find values for polymap
    for(X=0;X<1023;X++)
    {
        for(Y=0;Y<1023;Y++)
        {
            //Vertex [0]
            x=X;
            z=Y;
            y=Height(X,Y); 
            pos[0].x=x;
            pos[0].y=y;
            pos[0].z=z;
            
            
            //Vertex [1]
            x=X;
            z=Y+1;
            y=Height(X,Y+1); 
            pos[2].x=x;
            pos[2].y=y;
            pos[2].z=z;
            
            //Vertex [2]
            x=X+1;
            z=Y;
            y=Height(X+1,Y); 
            pos[1].x=x;
            pos[1].y=y;
            pos[1].z=z;
            
            PolyMap[X+(Y*1023)] = Normal(pos);
        }
    }
    
    //Find values for NormalMap based on polyMap
    for(X=1;X<1023;X++)
    {
        for(Y=1;Y<1023;Y++)
        {
            v1 = PolyMap[(X-1)+((Y-1)*1023)];

            
            v2 = PolyMap[(X)+((Y-1)*1023)];


            v3 = PolyMap[X+(Y*1023)];

            v4 = PolyMap[(X-1)+((Y)*1023)];

            
            normal = v1+v2+v3+v4;
            normal = Normalize(normal);
            NormalMap[X+(Y*1023)] = normal;
            
        }
    }
    
    delete[] PolyMap;
} 

void CIrisTerrain::Draw(int scale, int step, bool poly)
{
    int X, Y;
    int x,y,z;
    float col;
    CVector3 normal;
    
    
    glActiveTextureARB(GL_TEXTURE0_ARB);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D,TexID[0]);
    glActiveTextureARB(GL_TEXTURE1_ARB);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D,TexID[2]);
    if(poly==true)
    {
        glBegin(GL_QUADS);
    }else{
        glBegin(GL_LINES);
    }
    
    //loop
    for(X=0;X<(1024-step);X+=step)
    {
        for(Y=0;Y<(1024-step);Y+=step)
        {
            //Vertex 1
 			x = X;							
			y = Height(X, Y)/scale;	
			z = Y;
			col = 0.5+Color(y);
			glColor3f(col,col,col);
			
			normal.x = NormalMap[X+(Y*1023)].x;
			normal.y = NormalMap[X+(Y*1023)].y;
			normal.z = NormalMap[X+(Y*1023)].z;
			
			glNormal3f(normal.x,normal.y,normal.z);
            glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0,0);glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,0);
			glVertex3i(x, y, z);
			
			
			
			//Vertex 2
			x = X;										
			y = Height(X, Y + step)/scale;  
			z = Y + step ;
			col = 0.5+Color(y);
			glColor3f(col,col,col);
			
			normal.x = NormalMap[X+((Y+step)*1023)].x;
			normal.y = NormalMap[X+((Y+step)*1023)].y;
			normal.z = NormalMap[X+((Y+step)*1023)].z;
			
			glNormal3f(normal.x,normal.y,normal.z);
			
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0,1);glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,1);
			glVertex3i(x,y,z);
			
			
			//Vertex 3
			x = X + step;										
			y = Height(X+step, Y + step)/scale;  
			z = Y + step;
			col = 0.5+Color(y);
			
			normal.x = NormalMap[(X+step)+((Y+step)*1023)].x;
			normal.y = NormalMap[(X+step)+((Y+step)*1023)].y;
			normal.z = NormalMap[(X+step)+((Y+step)*1023)].z;
			
			glNormal3f(normal.x,normal.y,normal.z);
			
			glColor3f(col,col,col);
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1,1);glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1,1);
			glVertex3i(x,y,z);
			
			//Vertex 4
			x = X + step;										
			y = Height(X+step, Y)/scale;  
			z = Y;
			col = 0.5+Color(y);
			glColor3f(col,col,col);
			
			normal.x = NormalMap[(X+step)+((Y)*1023)].x;
			normal.y = NormalMap[(X+step)+((Y)*1023)].y;
			normal.z = NormalMap[(X+step)+((Y)*1023)].z;
			
			glNormal3f(normal.x,normal.y,normal.z);
			
			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1,0);glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1,0);
			glVertex3i(x,y,z);
			glColor3f(1,1,1);
			
			
		}
	}
	glEnd();
    glActiveTextureARB(GL_TEXTURE1_ARB);
    glDisable(GL_TEXTURE_2D);
    glActiveTextureARB(GL_TEXTURE0_ARB);
    
}


If anyone could just have a quick look through. Or just sugest something. Thx
------------ "Here lies a toppled God,His fall was not a small one,We but built his pedastle,A narrow, and a tall one" Frank Herbert (Dune:Messiah)
Advertisement
Quote:Original post by Kris2456
When you move the spotlight around, the terrain, instead of smoothly changing, goes very blocky. It looks light each square can only be lit up, or not lit up. It dosnt make it look very good.

That sounds like normal OpenGL spotlight behaviour, perhaps increase the size of the spotlight cone? I don't tend to use them that much 'cos the quality isn't much good. You'll probably get much smoother results with a point or directional light.

For debugging normals it generally helps to draw them at each vertex with a line. You can quickly eyeball your terrain and see if they're correct or not that way.
This is normal when using spotlights. If one vertex falls into the cone, that quad will look all weird and blocky. Increase the falloff radius to smooth things out, it should probably be greater than the size of your quads (or a few times that) to blend things good.
Hmm, your right.
When i move away from the terrain the spotlight looks much better. Anyway, i tried to have a look at my normals. But i couldnt get it too work. I tried this basicly:
glEnable(GL_LINES);    for(X=0;X<(1024-step);X+=step)    {        for(Y=0;Y<(1024-step);Y+=step)        {            //Vertex 1            glDisable(GL_TEXTURE_2D);            glColor3f(1,1,1); 			x = X;										y = Height(X, Y)/scale;				z = Y;						normal.x = NormalMap[X+(Y*1023)].x;			normal.y = NormalMap[X+(Y*1023)].y;			normal.z = NormalMap[X+(Y*1023)].z;						glVertex3i(x, y, z);			glVertex3f(x+normal.x, y+normal.y, z+normal.z);												//Vertex 2			x = X;													y = Height(X, Y + step)/scale;  			z = Y + step ;						normal.x = NormalMap[X+((Y+step)*1023)].x;			normal.y = NormalMap[X+((Y+step)*1023)].y;			normal.z = NormalMap[X+((Y+step)*1023)].z;						glVertex3i(x,y,z);			glVertex3f(x+normal.x, y+normal.y, z+normal.z);									//Vertex 3			x = X + step;													y = Height(X+step, Y + step)/scale;  			z = Y + step;						normal.x = NormalMap[(X+step)+((Y+step)*1023)].x;			normal.y = NormalMap[(X+step)+((Y+step)*1023)].y;			normal.z = NormalMap[(X+step)+((Y+step)*1023)].z;			glVertex3i(x,y,z);			glVertex3f(x+normal.x, y+normal.y, z+normal.z);						//Vertex 4			x = X + step;													y = Height(X+step, Y)/scale;  			z = Y;			normal.x = NormalMap[(X+step)+((Y)*1023)].x;			normal.y = NormalMap[(X+step)+((Y)*1023)].y;			normal.z = NormalMap[(X+step)+((Y)*1023)].z;						glVertex3f(x+normal.x, y+normal.y, z+normal.z);						glVertex3i(x,y,z);			glColor3f(1,1,1);					}	}	glEnd();	glEnable(GL_TEXTURE_2D);


The lines simply dont appear, i dont know why?
------------ "Here lies a toppled God,His fall was not a small one,We but built his pedastle,A narrow, and a tall one" Frank Herbert (Dune:Messiah)
You're not actually applying the vector direction to the vertex.
Example:
Vector v = Vector(vertex.x, vertex.y, vertex.z);
Vector n = Vector(normal.x, normal.y, normal.z);
glVertex3fv( v.v );
glVertex3fv( (v+n*10).v );//apply the normal direction to the vertex by ten units - assuming your normals are normalized.
Hmm, nope, stil lcnat see them. Also, the terrain looks incorrect, as the opposite side of the terrain looks lit up when using a positional light. Any ideas?
------------ "Here lies a toppled God,His fall was not a small one,We but built his pedastle,A narrow, and a tall one" Frank Herbert (Dune:Messiah)
Quote:Original post by Kris2456
*** Source Snippet Removed ***

The lines simply dont appear, i dont know why?

Er, glEnable(GL_LINES)?? Methinks you need a glBegin instead.
OMG, i am the biggest pecker in the world right now. Thx a lot for that, it wud have taken me ages to figure it out. Thx a lot.

The normals seem OK. so thats that.
------------ "Here lies a toppled God,His fall was not a small one,We but built his pedastle,A narrow, and a tall one" Frank Herbert (Dune:Messiah)
For better lighting you could increase the tesselation. It's also good to smooth out creases and sharp angles with more tris and smooth transition between peaks. On very sharp angles and opposite facing geometry your averaged vertex normal could become nulled or badly skewed.
Yeh, utried to use TRIANGLE_STRIPS. but it messed up. The terrain looked good, but there was this strange masssive quad where the floor should have beeen, and it was all distorted.
------------ "Here lies a toppled God,His fall was not a small one,We but built his pedastle,A narrow, and a tall one" Frank Herbert (Dune:Messiah)

This topic is closed to new replies.

Advertisement