Shadow- and cubemaps

Tried doing it in fragment shaders. Didn’t change much. God damn it! Sometimes I really wonder why nothing ever works when I try implementing.

Picture of negative Z cube face

Looking at your shaders, there seems to be quite a few problems.

First of all, you should really make sure that when outputting the color to the cube shadow map in your fragment program, the results are not outside the [0-1] range. Adding a saturate command might help here, although i’m not sure why your near objects would appear brighter than your far objects, as you supposedly write the light-space distance.

You are using the squared distance - not that’s it’s a bad thing - but then you should use 32 bits to store it, not only 8 bits. You are writing the same scalar value to all the RGBA components of the cube map, which effectively means that you’re encoding a squared distance with only 256 values - you’re not going to get something of quality here, if that even works… -. To use 32 bits, you should pack a float value into the 4 components via a FRAC instruction, and then extract it later with a DP4 instruction. Humus has a demo with shader code in ASM that shows that on his website, if it’s still down just let me know your email address and i’ll send it to you.

Finally, last but not least, i do not really understand how you’re performing the comparison when rendering your scene with phong lighting and the cube shadow map. In your current code, you set your “Distance” variable to 1.0/IN.att (which i supposed from the name hold an attenuation value), while you should instead be comparing to the to-light distance (basically using the same formula you used to generate the cube shadow map values).

My own shader looks like this (in ASM, sorry):

For the vertex shader, final lighting equation:

# cube map shadow lookup:
TEMP r0;
SUB r0, lightPosS, inPos;
MUL r0, r0, scale.x;
MOV outTex3, -r0;

(lightPosS is the light position, inPos is the vertex position, scale.x is 1.0 / Max Light radius).

Then the pixel shader:

TEX shadow, fragment.texcoord[3], texture[3], CUBE;
DP4 shadow, shadow, extract; # extract RGB to float

TEMP dist;
DP3 dist.w, fragment.texcoord[3], fragment.texcoord[3];
RSQ dist.x, dist.w;
MUL dist, dist.x, dist.w;
MUL dist, dist, 0.99; # bias to avoid Z-fighting
SGE shadow, shadow, dist; # comparison

Where fragment.texcoord[3] is the vertex-to-light vector interpolated per-pixel (NOTE: it should NOT be normalized in the vertex shader!), and extract is a constant vector containing these values: (X=1, Y=1/256, 1/256^2, 1/256^3) - see Humus explanations about packing/unpacking a float to the RGBA and vice-versa.

Y.

Originally posted by davepermen:
[b]hm. currently the page of humus is inaccesible for me, but theoretically, there would be some demos on how to pack one float into the 4 channels of an ordinary rgba texture, and unpack again, to do high depth precicion cubic shadow mapping

check Humus Page . But possibly, he gets a new host, on ati, or so, and thats why it’s down currently…[/b]
It’s just apache that has died for whatever reason, and I don’t have root access to restart the machine either. I’m gonna get my old roommate to restart it for me whenever I can reach him.

Ysaneya, thanks for your detailed reply. I’m sorry about that messed up shader code, I had done several changes to it became a bit confusing. The 1.0/Att thing was there because I needed the attenuation value, and I calculated it in the same way as the distance but only inverted.
I’ll try that packing asap and I think I got the idea (if I’m not mistaken, BMP format used that also for some reason).

Can you guys please confirm for me that the same technique of packing/unpacking vertex distance into RGBA texture would work for regular shadow maps, i.e. not using cubemap, but simply projecting the generated shadowmap (with vertex to light distance packed into RGBA) and then during shadow determination/lighting pass, passing the vertex to light distance in the same fashion and comparing that with the upacked RGBA value from shadowmap?

Yes, there’s no reason for it to not work.

To use 32 bits, you should pack a float value into the 4 components via a FRAC instruction, and then extract it later with a DP4 instruction.
would it be possible to have a deeper explanation on this ?

SeskaPeel.

Cut’n’pasted from my “shadows that rocks” demo:

Pack:

PARAM packFactors = { 1.0, 256.0, 65536.0, 16777216.0 };

MUL		dist, dist, packFactors;
FRC		output, dist;

Unpack:

PARAM extract = { 1.0, 0.00390625, 0.0000152587890625, 0.000000059604644775390625 };

DP4		shadow, shadow, extract;

Thanks Humus, got that one.

Let’s continue with the lameness : what improvements can provide glextended shadow mapping compared to packing a float in an RGBA texture ?

Is PCF for perspective correct filtering ? What is this supposed to do for me ?

SeskaPeel.

I’m probably also having some issues with Cg itself. Don’t know if it bugs or something (I’ve had some weird lighting results that no one could really have figure out) so I’ll give a shot for plain asm programs, just for testing. However, I’m not very familiar how to set it up and what’s the correct syntax for arb specific programs (only have a pdf for nv equvailent, which seems to differ a bit).

This is how I load a vertex program:
glEnable(GL_VERTEX_PROGRAM_ARB);
glGenProgramsARB(1, &ID);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, ID);
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, L_PROGRAM_FORMAT_ASCII_ARB, Size, Data);
glDisable(GL_VERTEX_PROGRAM_ARB);

And this is how I render:
glEnable(GL_VERTEX_PROGRAM_ARB);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, ID);
// Set up local vp variables
// Render
glDisable(GL_VERTEX_PROGRAM_ARB);

The same thing for fragment programs, except I change the type identifier.

Any good doc for arb vp/fp? The instructions are afaik pretty much the same as with nv, but setting up local variables etc. seems to differ.

Found a pdf for arb from the nv’s site :smiley: .