Depth in register combiner


I need to know the fragments depth (more precisely, the distance of a fragment from the light source) in a register combiner program on a GeForce 4.

I have tried to calculate the distance per vertex in a vertex program program and store the result in o[COL0]. I have clamped the distance to the range [0;1]. My question is
now: When I use the col0 register in the combiner program, does it contain the correct interpolated (to [0;1] clamped) depth of the fragment? The result I get looks rather strange. Is there any mistake in my approach or have I made an error in reasoning?

Any ideas?


Color interpolation is done linearly. Distance is nonlinear, but coordinate deltas are linear. So if you store the distance, then it won’t work quite right, but if you store the delta and use that to calculate the distance squared with a dot product, it should work.

I am not that experienced in using register combiners. You mean, I should store in o[COL0] the difference lightposition - vertexposition (both in modelspace). And then I can calculate the squared distance in register combiners by using the dot product.
But how can I get the squareroot of this dotproduct, the length of the distance of the fragment from the light source? Another question, how is col0 clamped to [0;1]? Deltas in the vertex program can be values > 500. I do not find anything in NVidias documentation about that. Sorry for asking maybe stupid questions, but I am a little bit confused. Thanks for any help.

You store positions as fractions of the cutoff radius, so that all three components are in the range [-1,1].

Frequently you can use distance squared instead of distance, though not always. If you can’t, then you can do a couple things instead on GeForce4 cards (assuming its not the MX, which is really a fast GF2). The easiest would be to store the length in a 3D texture, and to scale the [-1,1] coordinates into the [0,1] range instead. You could also use texture shaders to do the normalization. Both of these require storing position in a texture coordinate instead of a color, though.

Another thing you could do would be to tesselate your geometry to a high enough detail that the linear interpolation of distance is a “good enough” approximation to the real distance. Or, you could find an equation to get a better approximation to distance that can be evaluated in register combiners, and setup the constants for this equation in the vertex program.