Shadow mapping on a Geforce 2 + Nvidia "Shadowcast" demo

Started by
19 comments, last by godmodder 17 years, 11 months ago
Quote:Original post by deavik
bakery2k1, first of all thanks for sticking with me. After a lot of experimentation, I reversed the order of your matrix multiplies and it gives me this:


That looks promising!

Quote:The paper by MJK states "save the depth map as INTENSITY8" which is what I am doing. I don't exactly yet know how tex_env_combine works - but it's specifying the texture as a source of ALPHA. Does that mean the texture's internal format has to be ALPHA?


INTENSITY8 textures have all 4 RGBA components with the same value, so are perfectly valid to be used as a source of ALPHA.

Quote:If you suspect a particular portion of the code tell me I will post it.


If you're worried about your use of tex_env_combine, maybe we should have a look at that?
Advertisement
OK, now I have set both the textures to INTENSITY8 internal format. The next 2 images are the scene projectively textured with *only* the: a) depth map, b) depth ramp texture:

Free Image Hosting at www.ImageShack.us

Free Image Hosting at www.ImageShack.us

Now from those 2, I can see that subtracting the second from the first should "separate" out the shadowed portions. The texenv code:

	glActiveTexture(GL_TEXTURE0);	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);		glActiveTexture(GL_TEXTURE1);	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD_SIGNED);		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_ONE_MINUS_SRC_ALPHA);		glAlphaFunc(GL_GREATER, 0.5);	glEnable(GL_ALPHA_TEST);


TEXTURE0 holds the depth map texture, TEXTURE1 the 1D ramp texture. With that, the result is:

Free Image Hosting at www.ImageShack.us

However, another thing I am thinking about is that the bottom left portion of the "only depth ramp textured" scene is slightly darker than the "only depth map textured" scene - will subtracting them work? On the other hand, the bottom right hand corner of the combined textured scene looks OK (ie. not shadowed).

Thanks so much for your help so far!
Your texture combining code looks correct. Are you using polygon offset/only drawing back faces when drawing from the light's point of view? If not, try adding that.
So bakery21...does that mean you are Paul of Paul's Projects?
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
That's correct.
bakery2k1, I tried what you said, without success. However, I gott around to getting my head wrapped around texture combiners, and I think the condensed version below (which makes sense to me) is correct:
	// set texenv to combine	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);		// color = primary color	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);		// alpha = TEXTURE0 alpha + (1 - TEXTURE1 alpha) - 0.5	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE0);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE1);	glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_ONE_MINUS_SRC_ALPHA);	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD_SIGNED);		glAlphaFunc(GL_GREATER, 0.5);	glEnable(GL_ALPHA_TEST);


Now, the nett result of the alpha caluclation is (TEXTURE0 - TEXTURE1 + 0.5), and parts with alpha < 0.5 are rejected, right? Just to experiment I exchanged the the GL_SRC_ALPHA and GL_ONE_MINUS_ARC_ALPHA as operands 1 and 0 (so the new calculation is TEXTURE1 - TEXTURE0 + 0.5) and it gives me perfectly the result I expect: ie occluded from light parts unshadowed, and exposed parts shadowed. Take a look:

Free Image Hosting at www.ImageShack.us

You can even see where te self shadowing will happen! But I just can't figure out why just the opposite of this (which I want) is not happening ... arrrgh!
Quote:Original post by deavik
TEXTURE0 holds the depth map texture, TEXTURE1 the 1D ramp texture.


Are you sure of this? You may have the textures the wrong way round.

Quote:I think the condensed version below (which makes sense to me) is correct


That appears correct, but note that you are accessing both TEXTURE0 and TEXTURE1 in the combiner unit for texture 0. This is OK, but GL_COMBINE alone does not allow this - you are using "crossbar" texturing.
With my newfound knowledge of texture combiners [wink], I kept the alpha aources sign changed (as I wrote in the last post) and changed the AlphaFunc to GL_LEQUAL, and it works!

Free Image Hosting at www.ImageShack.us

BTW, is the texture combiner state maintained per texture unit? And what is "crossbar" texturing - accessing one texture unit from another?

bakery2k1, you practically tutored me to getting my first shadow map on screen! Thanks so much! [smile]
Quote:Original post by deavik
With my newfound knowledge of texture combiners [wink], I kept the alpha aources sign changed (as I wrote in the last post) and changed the AlphaFunc to GL_LEQUAL, and it works!


Well done! [smile]

Quote:BTW, is the texture combiner state maintained per texture unit? And what is "crossbar" texturing - accessing one texture unit from another?


In the fixed function pipeline (this no longer applies when you get into fragment shaders) each texture unit can perform (IIRC) one combination operation on the RGB components and another on the alpha components.

Using texture m as an operand in the combination on texture unit n (m != n) is called "crossbar" texturing. Certain older cards could support GL_COMBINE, but not crossbar texturing. Just about anything should support it nowadays though.
Thanks for the info!

Well I guess now that I've got the hang of my first shadowmap, like everyone else I'll try to improve on it. [smile]

Performance-wise of course I should try to cache the shadowmaps until the light / shadowcaster move, shouldn't I?

Apart from that - I know there are lots of shadowmap "improvement" methods out there - but what in your opinion is the best cost / quality wise that I should look at first? Without fragment shaders, that is ...

This topic is closed to new replies.

Advertisement