dot product 3

Started by
4 comments, last by Fyre_dragenn 21 years, 8 months ago
I''ve seen dot product 3 shading pop up every now and then, but l can''t imagine the use of it. Can anyone shed a little light please.
Advertisement
At the heart of most lighting equations are a few dot products:

For diffuse, you have L dot N, where L is the light direction vector or light to vertex vector and N is the normal to the surface being lit.

For specular you have N dot H, where N is N is the normal to the surface being lit and H is the [Blinn] "Half Vector". H=(L+V)/2) where L is the light vector as above and V is the "View" direction. The result of this is then raised to a power which controls the how sharp the highlights are [e.g. (N.H)**shininess]

With vertex lighting, these dot products are calculated for each vertex.

Now for an important realisation: RGB colour values can actually be thought of as vectors where R=X, G=Y, B=Z and the range of vales in an RGB colour component (0-255) can be thought of as a value between 0 and 1.

With this knowledge, having a dot product performed extremely fast (essentially 0-cost) in hardware for every pixel of a polygon becomes very useful! Anything which can store a colour in 3D hardware can store a vector, and most of those things can be inputs to the DOTPRODUCT3 blending operations!.

So in a texture for example, each pixel can store a vector, making the texture a 2D array of vectors!!. These vectors can be applied to a polygon so that every pixel of the polygon has a unique vector.

If you encode normal vectors into the pixel colours of a texture which is applied to a polygon, *every* pixel of that polygon has its own normal. This means every pixel can have its own orientation relative to a light source, it''s as if every pixel in the polygon were a tiny polygon with its own normal. For a rough/bumpy surface, the normals of these pixel sized surfaces would be pointing all over the place following the bumps. The lighting lights these accordingly - that''s why many people think of DOTPRODUCT3 as a bump mapping operation (really its a per-pixel lighting operation).

Finally (for diffuse) you need to get the light vector, L into a colour value. An obvious one is a texture constant (TFACTOR in D3D speak). Though for point lights you''ll end up using a per vertex colour (luckily vertex colours usually get interpolated across polygons by Gouraud shading, so it means your light vector gets interpolated by that mechanism!).

So the operation looks like:

TEXTURE DOTPRODUCT3 TFACTOR

where TEXTURE contains the normals, and TFACTOR contains the lights.


Simple eh ?...


There are a few gotchas, things I''ve skipped and more advanced areas though:

1) When you apply a texture to a polygon, it might be rotated, mirrored etc - when you do this with a normal map, the normal map itself is, BUT the vectors encoded by the normal map are NOT rotated so point in the wrong direction.

a. The simple solution is to have a unique texture for every polygon of an object and move the light into object space. Usually this isn''t practical due to memory constraints.

b. The more difficult (and slightly more CPU intensive) solution is to use texture space where each polygon has its own coordinate system and for each polygon the light vector is moved into this space. There''s a few other issues such as not being able to mirror polygons etc which affect texture space. I''ll leave that as an excercise for the reader to work out


2) I said that the colour component range of 0-255 mapped onto the vector component range of 0-1. I lied to keep things simple - In real life vectors can have negative components too. Really the hardware applies a bias to the colour inside the DOTPRODUCT3 operation to allow these negative values so really the colour components are mapped into the range -127 to 127.


3) DOT3 lets you get extremely close to proper Phong - the main restriction is that whereas Phong uses 32/64bit floating point values per pixel, DOT3 uses 7bits of integer precision per pixel. New & future hardware is getting better in this respect.


4) Think about the effects of bilinear filtering when a texture is stretched over a polygon. For a plain texture, the result is it goes blurry. Now think of what happens when you have vectors encoded in each of those pixels!!! - If you stretch normal maps, you end up with vectors which aren''t unit length. So the resultant lighting has "dark patches". Ideally you need to normalise the normal vector just before the operation...


5) Per pixel specular has some interesting problems:
a. Depending on exactly what you''re doing you need to be able to normalise certain vectors which are stored in colours. Normalising with straight texture ops isn''t really achievable so there are two common options: a "normalization cubemap" which is a cubemap texture you pass vectors into (using texture coordinates) to get a normalised *colour* out. Or use a pixel shader.

b. Doing the power/exponent for the shininess - how to raise it to a high enough power - you can use ADD, ADD2X and ADD4X type operations amongst others to get some of the way, but they burn texture stages. Pixel shaders are handy here, but still not ideal.

c. That 7-8bits of precision in a colour component often isn''t enough when doing all that stuff with the shininess - you lose precision from the values. The visual result of this is banding on your highlights.


Take a look at the nVidia and ATI (and other) developer websites for more information, papers, working code etc.

--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

If you can''t imagine a use for dot product 3 bumpmapping, just check out the Doom III screenshots .
Wow Simon, thanks for the great write up! I already knew a lot about Dot3 lighting, but you''ve managed to capture the what-it-is part rather nicely with the gotchas-of-using-it part. I''ve filed it away for future reference =)

BTW, for some real fun with shading check out nVidia''s anisotropic lighting hack. Actually, I hate that term, anisotropic lighting, since it''s such a bad description of something that can be adapted to work in so many fun ways!

-John
- John
Whoa! I never thought about all the uses, nor all the pitfalls. I think l''m might save this one for future use; I''m very impressed. I think a lot of people should read this one, too. I''m trying to keep away from pixel shaders because l feel that not enough gamers are have the supported hardware.
You don''t need pixel shaders for dot3 bumpmapping, GF1\Radeon+ cards support it through a texture blending operation.

This topic is closed to new replies.

Advertisement