Basic Register Combiner Questions

Recently, I dove into nVidia’s programmable aspects and after a bit of mind-wracking, finally got the basic gist of register combiners to come up with a very simple (but pride inducing) bump mapping routine when I should have been working this morning:

!!RC1.0
{
rgb
{
spare0=-expand(tex1).expand(const0);
}
}
out.rgb=spare0*tex0;
out.a=tex0.a;

I set const0 to be a vector indicating the incedent light prior to rendering; texture 0 is the texture map and texture 1 is the normal map. It’s not perfect (the dot product is not clamped to [0,1], and it’s not very efficient when you need to do a lot of non-coplanar faces) but it was a good sign to me that I was just starting to get a hang on this new tool.

Anyway, looking around the web, I grabbed a bunch of papers and presentations from nVidia, and I’ve been scouring opengl.org for information, but some stuff I just cannot find answers for. For example, what exactly does the discard register do? It seems to me to be a sort of stack, because I’ve seen combiners with code like this:

discard=something;
discard=somethingelse;
somethingnew=sum();

…and I assume the sum value takes into account the two previous assignments. Am I missing documentation somewhere? Additionally, as far as breaking combiners into stages; where does the line get drawn? How much can one stage do?

I’m looking forward to getting a hang on register combiners and moving into vertex programs later on; they seem to be documented more frequently and thoroughly.

Screw it, I figured it out in the mean time. It only took me about seven trips through John Spitzer’s texture blending presentation to get the point of it. Very informative, that.