Decomposing a Fragment Shader

There are still some things I’m having trouble doing. Maybe someone could help me decompose the following fragment program (taken from the ATI_text_fragment_shader spec):

The following is an example that performs bumped

cubic environment mapping:

!!ATIfs1.0

StartPrelimPass;
PassTexCoord r0, t0.str; # 1st row of 3x3 basis matrix
PassTexCoord r1, t1.str; # 2nd row of 3x3 basis matrix
PassTexCoord r2, t2.str; # 3rd row of 3x3 basis matrix
PassTexCoord r3, t3.str; # Eye vector
SampleMap r4, t5.str; # Sample normal map

Three dot products transform from tangent space to cube map space

DOT3 r0.r, r0, r4;
DOT3 r0.g, r1, r4;
DOT3 r0.b, r2, r4;

DOT3 r2.2x, r0, r3; # 2 * (N dot Eye)
MUL r2, r0, r2; # 2 * N * (N dot Eye)
DOT3 r1, r0, r0; # N dot N
MAD r1, r3.neg, r1, r2; # 2 * N * (N dot Eye) - Eye * (N dot N)
EndPass;

StartOutputPass;
SampleMap r0, r0.str; # Sample diffuse cubic env map
SampleMap r1, r1.str; # Sample specular cubic env map
SampleMap r2, t5.str; # Sample the base map (gloss in a)

MUL r0, r0, r2; # diffuse * base
MAD r0, r0, r2.a, r1; # (diffuse * base) + (spec * gloss)
EndPass;

Obviously just running this as my fragment program doesn’t work since I don’t have the proper values in the registers. But I can’t quite figure out what these values should be from the comments.

PassTexCoord r0, t0.str; # 1st row of 3x3 basis matrix
PassTexCoord r1, t1.str; # 2nd row of 3x3 basis matrix
PassTexCoord r2, t2.str; # 3rd row of 3x3 basis matrix
PassTexCoord r3, t3.str; # Eye vector

By “basis matrix” I’m guessing they mean a change of basis matrix. But for which bases? Is it a transformation from the standard basis? To the standard basis? I guess I’m just not familiar enough with OpenGL to understand that implicitly.

PassTexCoord r3, t3.str; # Eye vector
SampleMap r4, t5.str; # Sample normal map

“Eye vector” - is this the vector from the current fragment to the eye vector? How is this generated?
“normal map” - ok, I understand that this is the normal corresponding to the current fragment, but how do you specify that in your program (i.e., how do you generate the normal map other than a static texture you generate beforehand)? Why is it stored in texture register 5 (instead of the next one sequentially, 4)?

In general I’d like to know what these things are and how you assign them to the proper registers before they go to the fragment program. Sorry to say my knowledge of OpenGL is pretty hacked-together, which may explain some basic misunderstanding.

Thanks,

Keenan Crane
kcrane@uiuc.edu

The basis matrix is a column-major tangent basis matrix (because the normal map is stored in tangent space).

And actually, that shader can be cut back to 5 instructions in the first pass:

DOT3 r0.r, r0, r4;
DOT3 r0.g, r1, r4;
DOT3 r0.b, r2, r4;
DOT3 r2, r0, r3;
MAD r1, r2.2x, r0, r3.neg;

Ok, so the first part multiplies the basis matrix by the normal vector to go from the local (tangent) space of the norm to the space of the geometry of the object, correct?
But my question still stands - how do you generate the basis matrix for the norm, or rather, since it’s a map for all vectors in the normal map, how do you generate the map of basis matrices? I mean, I don’t understand how to interpret the geometry as a basis for the norm vectors, if that makes sense.

Thanks,

Keenan Crane
kcrane@uiuc.edu

Originally posted by Keenan Crane:
Ok, so the first part multiplies the basis matrix by the normal vector to go from the local (tangent) space of the norm to the space of the geometry of the object, correct?

Yes, it transforms the normal from tangent space to object space.

But my question still stands - how do you generate the basis matrix for the norm, or rather, since it’s a map for all vectors in the normal map, how do you generate the map of basis matrices? I mean, I don’t understand how to interpret the geometry as a basis for the norm vectors, if that makes sense.

It’s the same matrix for when doing DOT3 lighting. It’s composed of the tangent, binormal, and normal. Most DOT3 bump mapping tutorials cover how to calculate it.

Thanks! That’s exactly what I was looking for.

Keenan Crane
kcrane@uiuc.edu