Advertisement

Shadows totally black

Started by January 24, 2005 04:31 AM
2 comments, last by RipTorn 19 years, 10 months ago
i'm working on a small shadow mapping demo, i've downloaded the tutorial from paulsproject.net and modified the source in order to do only 2 rendering passes, and it works very well. And now my answer: there's a way to make the shadow "like penumbra" and not totally black? In the demo i cannot see the surfaces below the shadow, only a totally black area :/
IT depends on the way you render the shadow.

1. if you do it by not rendering where the shadow is, then you need a ambience pass (just do it at the same time you render the z buffer).

2. if you render the shadow by drawing a black polygon over the whole screen, then you need to make it a little semitransparent.

3. if you do it by making a texture of the stencil shadows and then multiplying it ontop of the renderd scene, then you need to draw a dark grey one one blended polygon ontop of the shadow texture just before you use it as a texture.
Advertisement
i've implemented only a simple case of shadow mapping, here's part of my code:
//First pass - from light's point of view	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		glMatrixMode(GL_PROJECTION);	glLoadMatrixf(lightProjectionMatrix);	glMatrixMode(GL_MODELVIEW);		glLoadIdentity();	gluLookAt(	lightPosition.x, lightPosition.y, lightPosition.z,				0.0f, 0.0f, 0.0f,				0.0f, 1.0f, 0.0f);	glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMatrix);	glLoadMatrixf(lightViewMatrix);	//Use viewport the same size as the shadow map	glViewport(0, 0, shadowMapSize, shadowMapSize);	//Draw back faces into the shadow map	glCullFace(GL_FRONT);	//Disable color writes, and use flat shading for speed	glShadeModel(GL_FLAT);	glColorMask(0, 0, 0, 0);	glEnable(GL_POLYGON_OFFSET_FILL);	glPolygonOffset(4,4);	//Draw the scene	DrawScene(angle);	glDisable(GL_POLYGON_OFFSET_FILL);	//Read the depth buffer into the shadow map texture	glBindTexture(GL_TEXTURE_2D, shadowMapTexture);	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);	//restore states	glCullFace(GL_BACK);	glShadeModel(GL_SMOOTH);	glColorMask(1, 1, 1, 1);	//2rd pass	//Draw with bright light		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	glMatrixMode(GL_PROJECTION);	glLoadMatrixf(cameraProjectionMatrix);		glMatrixMode(GL_MODELVIEW);	glLoadMatrixf(cameraViewMatrix);//	glViewport(0, 0, windowWidth, windowHeight);	glLightfv(GL_LIGHT1, GL_POSITION, VECTOR4D(lightPosition));	glEnable(GL_LIGHT1);	glEnable(GL_LIGHTING);	glLightfv(GL_LIGHT1, GL_DIFFUSE, white);	glLightfv(GL_LIGHT1, GL_SPECULAR, white);	//Calculate texture matrix for projection	//This matrix takes us from eye space to the light's clip space	//It is postmultiplied by the inverse of the current view matrix when specifying texgen	static MATRIX4X4 biasMatrix(0.5f, 0.0f, 0.0f, 0.0f,								0.0f, 0.5f, 0.0f, 0.0f,								0.0f, 0.0f, 0.5f, 0.0f,								0.5f, 0.5f, 0.5f, 1.0f);	//bias from [-1, 1] to [0, 1]	MATRIX4X4 textureMatrix=biasMatrix*lightProjectionMatrix*lightViewMatrix;	//Set up texture coordinate generation.	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);	glTexGenfv(GL_S, GL_EYE_PLANE, textureMatrix.GetRow(0));	glEnable(GL_TEXTURE_GEN_S);	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);	glTexGenfv(GL_T, GL_EYE_PLANE, textureMatrix.GetRow(1));	glEnable(GL_TEXTURE_GEN_T);	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);	glTexGenfv(GL_R, GL_EYE_PLANE, textureMatrix.GetRow(2));	glEnable(GL_TEXTURE_GEN_R);	glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);	glTexGenfv(GL_Q, GL_EYE_PLANE, textureMatrix.GetRow(3));	glEnable(GL_TEXTURE_GEN_Q);	//Bind & enable shadow map texture	glBindTexture(GL_TEXTURE_2D, shadowMapTexture);	glEnable(GL_TEXTURE_2D);	//Enable shadow comparison	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);	glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA16);	DrawScene(angle);	//Disable textures and texgen	glDisable(GL_TEXTURE_2D);	glDisable(GL_TEXTURE_GEN_S);	glDisable(GL_TEXTURE_GEN_T);	glDisable(GL_TEXTURE_GEN_R);	glDisable(GL_TEXTURE_GEN_Q);	//Restore other states	glDisable(GL_LIGHTING);


and the texture is created this way:
glGenTextures(1, &shadowMapTexture);	glBindTexture(GL_TEXTURE_2D, shadowMapTexture);	glTexImage2D(	GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapSize, shadowMapSize, 0,					GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

not sure what you mean by "like penumbra"

to add ambient without shaders you need a second pass. To add more light from another source without shaders (and often with), you also need a second pass. With lighting second passes are always additive.

but technically, if there is just one light, then you would want the shadow to be solid black. When another light is added to your scene, and it is drawn in a second pass, then those blacks areas will hopfully get lit up by the second light. Accumulated lights look really really cool :)

I suppose if you left in a bit of light from the light source then you might be able to achieve a slight, fake-radiosity effect.. But that would need shaders. Shadow maps compute to be either zero or one. You can't say you want the shadow to be 0.1. (well, tehnically you can if your using various SGI extensions [wink])

if your asking for how to do soft shadows, then thats not easy. In fact it's really hard [smile] - needs lots of crazy shaders usually and is buggy.

ambient light is useful, but is very hard to use properly. Often times real-world ambient varies enormously. Imagine a house on a landscape. Outside, the ambient might be bright blue from the general light being scattered from the blue-sky, but inside the hut, there is very little scattered light off the dark brown log walls.. So a bright blue ambient would look bad inside and a dark brown ambient would look positivly stupid outside. :/ (yay for global illumination here I guess ;)

ahh well I have no idea what your asking still so I just rambled on a bit like I normally do.

This topic is closed to new replies.

Advertisement