lighting problem on narrow shapes

I’m experiencing a weird problem where the diffuse lighting appears to be affected by the size of the shape i’m drawing.

As an exercise, I wrote a simple recursive function that uses the matrix stack and some randomizations to draw tree branches. Each tree branch is thinner than the branch from which it emerged by a constant factor. (currently, 0.6). But for some odd reason, the really thin branches are turning out to be a brighter color than the thick branches. This seems to be due to diffuse or specular lighting, because they go away when i just use ambient lighting.

Here’s a screenshot:

or if that doesn’t work, go
http://i21.photobucket.com/albums/b299/mikau16/treeGL.png

If I make the scaling factor between a branch and its trunk (1), so the thickness doesn’t decrease, the problem goes away. However, if I then make the thickness of the entire tree very thin, all the branches get brightly colored, like the top branches.

Lastly, it doesn’t depend on the number of pixels used, becuase if i call glTranslate to move the tree close to the viewer, the branches naturally occupy more pixels,but the color stays the same.

Here’s the code for the branch drawing routine:


void drawBranch(float thickness,float length, float x, float y, float z, int depth)
{
	glPushMatrix();
	glTranslatef(x,y,z);
	glScalef(thickness,length,thickness);
	//draw vertical branch at x,y,z
	glColor3f(0.2,0.1,0);
	drawCube();
	glPopMatrix();
	
	depth--;
	int branchFactor=random(2,6);
	int leafCount=4;

	if (depth <= 0)
	return;

	glTranslatef(0,2*length,0);

	for (int i = 0; i < branchFactor; i++)
	{
		glPushMatrix();
		
		float angle=(float)i*360/branchFactor;
		glRotatef(angle,0,1,0);
		angle=random(15,45);
		glRotatef(angle,1,0,0);
		drawBranch(thickness*0.6, length*0.9, 0,0,0,depth);

		glPopMatrix();
	}
				
}

heres my lighting initialization


void initializeLighting()
{
	
	glEnable(GL_LIGHTING);	
	
	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);

	float matAmbient[3]={0.2,0.2,0.2};
	float matDiff[3]={0.2,0.2,0.8};
	float matSpec[3]={0.2,0.2,0.2};

	float lightPosition[4]={0,0,0,1}; // location
	float ambientLight[3]={1.0,1.0,1.0};
	float diffuseLight[3]={1.0,1.0,1.0};
	
	glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,matAmbient);
	glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,matDiff);
	//glMaterialfv(GL_FRONT,GL_SPECULAR,matSpec);
	glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,64);

	glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
	glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
	glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);

	glEnable(GL_LIGHT0);

}

note I’m using colorMaterial so I can set the diffuse and ambient color with glColor3f()

and I guess I might as well include my ‘drawCube’ function:


void drawCube()
{
	glBegin(GL_QUADS);
		glNormal3f(0,1,0);
		glVertex3f( 1.0f, 2.0f,-1.0f);			
		glVertex3f(-1.0f, 2.0f,-1.0f);			
		glVertex3f(-1.0f, 2.0f, 1.0f);			
		glVertex3f( 1.0f, 2.0f, 1.0f);			

		glNormal3f(0,-1,0);
		glVertex3f( 1.0f,0.0f, 1.0f);			
		glVertex3f(-1.0f,0.0f, 1.0f);			
		glVertex3f(-1.0f,0.0f,-1.0f);			
		glVertex3f( 1.0f,0.0f,-1.0f);			
		
		glNormal3f(0.0,0.0,1.0);
		glVertex3f( 1.0f, 2.0f, 1.0f);			
		glVertex3f(-1.0f, 2.0f, 1.0f);			
		glVertex3f(-1.0f,0.0f, 1.0f);			
		glVertex3f( 1.0f,0.0f, 1.0f);	

		glNormal3f(0.0,0.0,-1.0);
		glVertex3f( 1.0f,0.0f,-1.0f);			
		glVertex3f(-1.0f,0.0f,-1.0f);			
		glVertex3f(-1.0f, 2.0f,-1.0f);			
		glVertex3f( 1.0f, 2.0f,-1.0f);			

		glNormal3f(-1.0,0.0,0.0);
		glVertex3f(-1.0f, 2.0f, 1.0f);			
		glVertex3f(-1.0f, 2.0f,-1.0f);			
		glVertex3f(-1.0f,0.0f,-1.0f);			
		glVertex3f(-1.0f,0.0f, 1.0f);			

		glNormal3f(1.0,0.0,0.0);
		glVertex3f( 1.0f, 2.0f,-1.0f);			
		glVertex3f( 1.0f, 2.0f, 1.0f);			
		glVertex3f( 1.0f,0.0f, 1.0f);			
		glVertex3f( 1.0f,0.0f,-1.0f);			

		glEnd();
}

Per vertex lighting is usually not very accurate, maybe that’s the problem…

Check pitfall number “1. Improperly Scaling Normals for Lighting” :
http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/

Just put this at the beginning :
glEnable(GL_NORMALIZE);

Thanks, ZBuffer! :] Its working fine now! I’ll be sure to read through more of those pitfalls as I encounter those topics.