On GeForce3 you may not need to waste a texture unit on a normalization cube map. You can approximate normalization with the technique described below. Normalization in the combiners also allows you to do more interesting things with normal maps, like alter the direction (with a non-uniform “bump scale”), add two or more normal vectors (“detail normal map” applied to a base normal map). There are probably many others. I encourage you to play around with this technique.
The approximation comes from Scott Cutler of NVIDIA, and is:
vec3 approx_normalize(const vec3 & v) { float approx_factor = (3 - <v,v> ) / 2; vec3 v' = v * approx_factor; return v'; }
Using the nvparse RC1.0 register combiners description language,
this is the setup for normalizing primary color (col0). The input is
range compressed [0,1] since vertex colors can’t be signed. The
output is not range compressed, and it’s stored back in col0.
!!RC1.0 // col0 is a range compressed vector in [0,1] // col0 is *less* than unit length { // combiner0 rgb { // normalize col0 -- step 1 spare0 = expand(col0) . expand(col0); } } { // combiner1 rgb { // normalize col0 -- step 2 discard = expand(col0); discard = half_bias(col0) * unsigned_invert(spare0); col0 = sum(); } } //... further combiners use col0 as a normalized vector in [-1,1] out.rgb = ...; out.a = ...;
That’s pretty much it. If you do the algebra, those combiner contortions map to
the “c-like” expression above. It uses the RGB portion of 1.5 general combiners.
Not too bad, and the results are really nice. Hope you can use this.
The latest SDK has an example of this in the Earth Sphere (bump_mapping__step_2)
demo.
Rich Geldreich, an XBox game developer, independently came up with a cubic approximation to normalization within the register combiners.
John Spitzer will be presenting this and related material in an upcoming NVIDIA whitepaper on register combiners and techniques that use them.
Thanks -
Cass
[This message has been edited by cass (edited 05-23-2001).]