help with improving realism of 3D shadow casting

maybe this is better for the beginner forum, since i’m a beginner - but here goes. i’m rendering a top view of a cube with several spotlights overlapping. i’m having some trouble getting the shadows to overlap in a realistic way. basically i draw the light circles and then the shadows, plus some blurring, and have experimented with all the blending modes and various alpha values, but can’t get it quite right. this is a clumsy attempt, so perhaps i’m just doing this type of thing fundamentally wrong.

the problem is when the shadows are drawn very dark (which approximates reality closer, i.e. absence of a given light), the areas of shadow in another light’s circle are too dark.
http://www.ericforman.com/-projects/sha-…-hadows.png

when the shadows are drawn lightly (e.g. 50% alpha), the areas of shadow overlapping look correct (very dark), but the shadows outside that are too light.
http://www.ericforman.com/-projects/sha-…-hadows.png

here is a quick render from Blender showing (kinda) how it should look:
http://www.ericforman.com/-projects/shadow/3Drender.png

here is some of my code:

  
  
void testApp::draw(){  
	char reportStr[1024];  
	  
	glClear (GL_COLOR_BUFFER_BIT);  
	  
 	glEnable(GL_BLEND);  
 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  
	  
	// draw lights  
	for (int i = 0; i < contourFinder.nBlobs; i++){			  
		lightCenter[0] =  ((contourFinder.blobs[i].centroid.x) - 320/2)*4;  
		lightCenter[1] =  ((contourFinder.blobs[i].centroid.y) - 240/2)*4;			  
		drawBlurSpot(30, 0.4f, 2.0f);	  
	}  
	  
	// draw shadows  
	for (int i = 0; i <contourFinder.nBlobs; i++){		  
		lightCenter[0] =  ((contourFinder.blobs[i].centroid.x) - 320/2)*4;  
		lightCenter[1] =  ((contourFinder.blobs[i].centroid.y) - 240/2)*4;		  
		drawBlurShadow(15, 1.0f, 5.0f);	  
	}  
	  
	// ...  
	  
	glDisable(GL_BLEND);   
	  
	  
	// ...  
}  
  
  
void testApp::drawShadow(){	  
 	glDisable(GL_DEPTH_TEST);  
	  
	findplane(plane, v0, v1, v2);  
	shadowmatrix(floorshadow, plane, lightpos);	  
	  
	glPushMatrix();  
	glMultMatrixf((GLfloat *) floorshadow); 	  
	glTranslatef(-50.f, -50.f, 0.f);  
	drawCube();	 	  
	glPopMatrix();  
	  
	glEnable(GL_DEPTH_TEST);	  
}  
  
  
void testApp::drawBlurShadow(int blurTimes, float alpha, float lightOffset){  
	for(int b=0; b<blurTimes; b++){		  
		glPushMatrix();  
		lightpos[0] = lightCenter[0] - lightCenter[0]*((b*lightOffset)/lightHeight);  
		lightpos[1] = lightCenter[1] - lightCenter[1]*((b*lightOffset)/lightHeight);  
		lightpos[2] = lightHeight - b*lightOffset;  
		  
		glTranslatef(ofGetWidth()/2 , ofGetHeight()/2 , 0);  
	  	glColor4f(0.0, 0.0, 0.0, (1.f/blurTimes)*alpha);  
		drawShadow();  
		glPopMatrix();  
	}		  
}  
  
  
void testApp::drawSpot(){  
	glDisable(GL_DEPTH_TEST);  
	findplane(plane, v0, v1, v2);  
	shadowmatrix(floorshadow, plane, lightpos);  
	  
	glPushMatrix();  
	glMultMatrixf((GLfloat *) floorshadow);   
	//glTranslatef( (mouseX-150) *(200/300),  (mouseY-150) *(200/300), 100.f);  
	glTranslatef(0, 0, 100.0f);  
	sphere = gluNewQuadric();  
	gluSphere(sphere, 100.f, 50, 50);  
	gluDeleteQuadric(sphere);	  
	glPopMatrix();  
	glEnable(GL_DEPTH_TEST);  
}  
  
  
void testApp::drawBlurSpot(int blurTimes, float alpha,  float lightOffset){	  
	for(int b=0; b<blurTimes; b++){		  
		glPushMatrix();  
		lightpos[0] = lightCenter[0] - lightCenter[0]*((b*lightOffset)/lightHeight);  
		lightpos[1] = lightCenter[1] - lightCenter[1]*((b*lightOffset)/lightHeight);  
		lightpos[2] = lightHeight - b*lightOffset;  
		  
		glTranslatef(ofGetWidth()/2 , ofGetHeight()/2 , 0);  
		glColor4f(1.0, 1.0, 1.0, (1.f/blurTimes)*alpha);  
		drawSpot();  
		glPopMatrix();  
	}	  
}  
  

what would be a better approach? any other general code tips welcome too.

thanks

e

oh, here is the shadowMatrix:

  
  
/* create a matrix that will project the desired shadow */  
void shadowmatrix(GLfloat shadowMat[4][4],      // shadowMat is the float to return  
				  GLfloat groundplane[4],  
				  GLfloat lightpos[4]) {  
	  
	GLfloat dot;  
	  
	// find dot product between light position vector and ground plane normal  
	dot = groundplane[X] * lightpos[X] +  
    groundplane[Y] * lightpos[Y] +  
    groundplane[Z] * lightpos[Z] +  
    groundplane[W] * lightpos[W];  
	  
	shadowMat[0][0] = dot - lightpos[X] * groundplane[X];  
	shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];  
	shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];  
	shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];  
	  
	shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];  
	shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];  
	shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];  
	shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];  
	  
	shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];  
	shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];  
	shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];  
	shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];  
	  
	shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];  
	shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];  
	shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];  
	shadowMat[3][3] = dot - lightpos[W] * groundplane[W];  
}