A few days ago I followed a thread on the Game Developer Algorithms forum. A lot of people exchanged ideas on how the lighting in DOOM III might work. The basis of this discussion was the interview with John Carmack at Beyond3D.
After thinking for myself for some time, I came up with the following example programs. They should show a few basic ideas, that might be useful to create a similar lighting effect as used in DOOM III. Perhaps this might help others to research the lighting algorithm in more detail, after the game is released.
What You Need to Know/Equipment
This will show you variations on diffuse and specular lighting. You will find an extensive explanation of the used diffuse and specular lighting algorithms in the four introductory articles published on www.direct3d.net and www.gamedev.net.
To get a real-time visual experience of the effects shown in the example programs, a modern graphics card is needed, because these programs are using pixel shaders, that are not emulated in software like vertex shaders. Without pixel shaders supported in hardware, the whole graphics pipeline would run in the reference rasterizer.
Check the cap bits in the DirectX caps viewer for support of the proper pixel shader version. Some of the examples require the support of ps.1.1, one example at least ps.1.2 and the last examples requires support for ps.1.4. Additionally you need the newest graphic card driver for those cards.
For Geforce 4TI graphics cards, you need a device driver with a higher version number than 30.82 to be able to see the ps.1.2 example running.
What You Are Going To Learn
The target of this article is to show ways how to improve the visual appearance of diffuse and specular reflections on graphic cards with a low level of color precision. Additionally this article will show how to split up an effect into multiple render passes to make it working with a ps.1.1 pixel shader.
The first of the upcoming examples RacorX10 will show you, how to use an illumination map that holds diffuse and specular reflection values. This example additionally uses a gloss map to facilitate a per-pixel specular reflection. To get a point light effect, this example and the other examples use a 2D/1D attenuation map, that should be compatible with all ps.1.1 graphics cards. One of the gotchas this example should show is the usage of multiple passes to achieve the diffuse/specular/point light effect.
The next example called RacorX11 uses additionally a cube normalization map to normalize the light vector, so that the diffuse lighting effect has a higher quality. Whereas RacorX10 only uses two passes to show the lighting effect, this example needs three passes, because of the small number of pixel shader instructions possible in a ps.1.1 shader.
RacorX12 implements all features of RacorX11, but uses a ps.1.2 pixel shader to achieve the same effect. This leads to a reduction of the passes necessary and an improvment of speed.
RacorX13 implements all the features of RacorX11 with a ps.1.4 pixel shader. Compared to RacorX12 this leads to a further reduction of passes. This example creates the same effect that is shown in RacorX11 in only one pass, compared to the three passes used by the latter.
RacorX14 is a vastly improved version of RacorX13, because it uses ps.1.4 specific optimizations, that lead to a reduction of the number of used texture stages and to an improvement of the visual quality. It additionally normalizes the half vector with a cube normalization map.