Contents
Messing with Tangent Space
 
 
Printer-Friendly VersionPrinter-Friendly Version
 
Latest News
spacer View All spacer
 
November 22, 2009
 
Video Game Watchdog National Institute On Media And The Family Shutting Down [11]
 
Modern Warfare 2 Infinity Ward's 'Most Successful PC Version' Yet [12]
 
New Tech, Design Details Of Project Natal To Emerge At Gamefest In February
spacer
Latest Jobs
spacer View All     Post a Job     RSS spacer
 
November 22, 2009
 
Sucker Punch Productions
Character Artist
 
Sucker Punch Productions
3D Environment Artist
 
Sucker Punch Productions
Network Programmer
 
Sucker Punch Productions
Texture Artist
 
Sony Online Entertainment
Brand Manager
 
Monolith Productions
Sr. Software Engineer, Engine - Monolith Productions - #113767
 
Crystal Dynamics
Sr. Level Designer
 
Gargantuan Studios
Lead World Designer
spacer
Latest Features
spacer View All spacer
 
November 22, 2009
 
arrow Upping The Craft: Susan O'Connor On Games Writing [6]
 
arrow Small Developers: Minimizing Risks in Large Productions - Part II [6]
 
arrow iPhone Piracy: The Inside Story [48]
 
arrow And Yet It Grows: Analyzing the Size and Growth of the European Game Market [5]
 
arrow NPD: Behind the Numbers, October 2009 [13]
 
arrow Reflecting On Uncharted 2: How They Did It [5]
 
arrow Sponsored Feature: Rasterization on Larrabee -- Adaptive Rasterization Helps Boost Efficiency
 
arrow Postmortem: Wadjet Eye's The Blackwell Convergence [2]
spacer
Latest Blogs
spacer View All     Post     RSS spacer
 
November 22, 2009
 
Accepting the Inherent Value of Games
 
Planckogenesis, Part II: Song Structure & Gravy Train [1]
 
Designing Games Is About Matching Personalities [1]
spacer
About
spacer News Director:
Leigh Alexander
Features Director:
Christian Nutt
Editor At Large:
Chris Remo
Advertising:
John 'Malik' Watson
Recruitment/Education:
Gina Gross
 
Features
  Messing with Tangent Space
by Siddharth Hegde
5 comments
Share RSS
 
 
July 16, 2007 Article Start Previous Page 5 of 7 Next
 

4. Per-Pixel lighting using vertex and pixel shaders

In this section I will put all the boring mathematics discussed in the previous section to some real use.

I am assuming that you understand the basics of vertex and pixel shaders. I also assume you are familiar with the DirectX 9 API as I will make no attempt to explain functions from the D3D9 API here. Another point to remember is that I'm not going to try to teach you shaders here. The purpose of this section is to understand a practical use for all that was explained above.
Another assumption is that when I refer to a light I am referring to a point light.
I will only discuss calculating the diffuse component of a light to a surface here. There are several other calculations that need to be done in order for the lighting to look realistic. These would include attenuation, specular, and many other components. These are beyond the scope of this article and you can find several good articles covering these topics.

Advertisement

So what is per-pixel lighting

Previously lighting (color and brightness) was calculated at the vertex level and then interpolated across the surface of the face. This worked well if the model had an extremely high polygon count, but most games were required to keep the polygon count to a minimum in order to maximize their efficiency and in turn the FPS. In almost all cases teams went with vertex lighting only on player characters and the rest of the scene was lit statically via textures using lightmaps. Lightmaps work well, really well. You can have soft shadows, and very accurate lighting calculation, but one very serious drawback is that it works only if the objects are static at run-time. This is exactly the opposite of what a player expects in a game. A player expects everything to move and break (and a lot more than that too…). So most game design teams made a balance of dynamic objects to the non dynamic ones. The dynamic objects had a high poly count in many cases, so the vertex lighting on them worked well.

And then there was light…
And then when graphics cards became powerful enough, we found new ways [algorithms] to calculate light at every pixel. Now these are not entirely accurate, but as we know as long as it looks realistic enough, it works.

Most 3D APIs have vertex level lighting built into the API itself. But with per-pixel lighting we need to do it on our own. With per pixel lighting, every pixel point [texel] can have it’s own normal. Now we can have high resolution bumpy surfaces without worrying about the poly count of the object.

How light affects a surface and limitations in a traditional vertex lighting

Before we go to the actual calculations, lets quickly revise how a light affects a surface.

Figure 9: Amount of diffuse lighting reflected by a surface

The diffuse component of how much a light affects a surface can be rounded off to the following equation.

IL = cos(θ)

Where

IL = the intensity of light
θ = the angle between the surface and the light

Take a look at Figure 9. It shows how the position of a light affects how brightly a surface is lit. L signifies the position of a light and N is the surface normal. We assume that the distance between the point and the light remain the same. As the light L makes an angle closer to 90o, the surface becomes darker and darker.

Now the problem with traditional lighting is that the brightness with which a surface is lit is determined at the vertex level. If you look at the texture mapped face in Figure 9, you will see that even though the texture signifies bumps on the surface, the entire surface is uniformly lit regardless of the surface orientation at each texel. This means that the entire surface is dark or the entire surface is lit evenly. This will work fine only when the face makes up only a small part of the surface.

This is where per-pixel lighting comes in. In per-pixel lighting the brightness of the surface is determined at each texel instead of at each vertex, thus increasing the realism dramatically.

How bump mapping works

Figure 10: A height map and it's corresponding lightmap on the right

While doing bump mapping, in addition to the normal diffuse texture used, an additional texture called a normal map is used.

A normal map determines the orientation of the surface at each texel. Before we continue, don't be confuse a normal map with a height map or bump map as it is known in some 3D editing software such as 3D studio Max. Yes, a height map can be used for bump mapping, but it must be converted to a normal map before it can be used.

 
Article Start Previous Page 5 of 7 Next
 
Comments

Kiran Sudhakara
profile image
Step 2: Calculate the T vector
T = E2-1.xyz / E2-1.u

This formula does not seem correct. Wouldn't this just scale the edge?

David Larsson
profile image
Responce to Kiran's comment:

I think the formula is supposed to be more like this(could be wrong though):

NE2-1 = Normalize(E2-1)
NE3-1 = Normalize(E3-1)
T = (NE2-1.xyz / E2-1.u) + (NE3-1.xyz / E3-1.u)

Kiran Sudhakara
profile image
Unfortunately I believe this is wrong aswell. Consider a simple case where E2-1.uv is 1,0 (so E2-1.xyz is already the tangent!), and E3-1.uv is an angled vector across the UV space.

Shih-Kai Lai
profile image
http://www.terathon.com/code/tangent.html
http://www.blacksmith-studios.dk/projects/downloads/tangent_matrix_derivation.ph
p

These 2 website have good explanations about tangent space.

Does any body know, if 2 vertex of a triangle have the same UV, then should I ignore that triangle, or ask art to change the UV? The determinant will become 0 in this case...

Julian Hainsworth
profile image
No two vertices should have the exact same UV-Coords, if this is a problem with your meshes you should see your artist


none
 
Comment:
 


Submit Comment