Return to main page

Doom3 and Quake4 rendering improvement

A lot of people have thought about improve rendering speed of Doom3 engine by computing the light vector(and the half vector) instead of using a normalization cubemap. I propose to improve rendering quality of Doom3 engine (used also in Quake4) by renormalizing the local surface normal read from the normal map for each pixel.

A surface local normal vector is stored in a normalmap with 8 bits per component so it authorizes only 256 values. So each component of the normalmap is compressed to a 8 bits positive integer number and it has to handle negative values so we have 128 values for the positive range and 128 values for the negative range. This lack of precision results in visible seam and artifact on lit surfaces. The advantage of normal normalization is better surface definition and better quality (non-normalized normals due to linear interpolation no longuer exist).

So, in the surface shader, we change the following code :

   TEX localNormal, fragment.texcoord[1], texture[1], 2D;
   MOV localNormal.x, localNormal.a;
   MAD localNormal.xyz, localNormal, 2.0, -1.0;

To :

   TEX localNormal, fragment.texcoord[1], texture[1], 2D;
   MOV localNormal.x, localNormal.a;
   #we have only a 0.5 soustraction because we are going to normalize so no muliplication by 2...
   ADD localNormal.xyz, localNormal, -0.5;
   #normalize local normal to improve rendering quality!
   DP3 tmp.w, localNormal, localNormal;
   RSQ tmp.w, tmp.w;
   MUL localNormal.xyz, tmp.w, localNormal;

See the zip file for install instruction. To be able to take advantage of this modification, you must use ARB2 code path (use the r_renderer command in the console to check this).

Download source and executable

Normal rendering
With normal renormalization : better surface definition like the circle,
the floor or far away tubes.

 

Normal rendering
With normal renormalization : better surface definition like gun details

Return to main page