iPhone 3D Programming : Adding Depth and Realism - Lighting Up (part 1)

1/9/2011 4:30:13 PM
The foundations of real-time graphics are rarely based on principles from physics and optics. In a way, the lighting equations we’ll cover in this section are cheap hacks, simple models based on rather shallow empirical observations. We’ll be demonstrating three different lighting models: ambient lighting (subtle, monotone light), diffuse lighting (the dull matte component of reflection), and specular lighting (the shiny spot on a fresh red apple). Figure 1 shows how these three lighting models can be combined to produce a high-quality image.
Figure 1. Ambient + diffuse + specular = final

Of course, in the real world, there are no such things as “diffuse photons” and “specular photons.” Don’t be disheartened by this pack of lies! Computer graphics is always just a great big hack at some level, and knowing this will make you stronger. Even the fact that colors are ultimately represented by a red-green-blue triplet has more to do with human perception than with optics. The reason we use RGB? It happens to match the three types of color-sensing cells in the human retina! A good graphics programmer can think like a politician and use lies to his advantage.

1. Ho-Hum Ambiance

Realistic ambient lighting, with the soft, muted shadows that it conjures up, can be very complex to render , but ambient lighting in the context of OpenGL usually refers to something far more trivial: a solid, uniform color. Calling this “lighting” is questionable since its intensity is not impacted by the position of the light source or the orientation of the surface, but it is often combined with the other lighting models to produce a brighter surface.

2. Matte Paint with Diffuse Lighting

The most common form of real-time lighting is diffuse lighting, which varies its brightness according to the angle between the surface and the light source. Also known as lambertian reflection, this form of lighting is predominant because it’s simple to compute, and it adequately conveys depth to the human eye. Figure 2 shows how diffuse lighting works. In the diagram, L is the unit length vector pointing to the light source, and N is the surface normal, which is a unit-length vector that’s perpendicular to the surface. 

Figure 2. Diffuse lighting

The diffuse factor (known as df in Figure 2) lies between 0 and 1 and gets multiplied with the light intensity and material color to produce the final diffuse color, as shown in Diffuse color.

Diffuse color

df is computed by taking the dot product of the surface normal with the light direction vector and then clamping the result to a non-negative number, as shown in Diffuse coefficient.

Diffuse coefficient

The dot product is another operation that you might need a refresher on. When applied to two unit-length vectors (which is what we’re doing for diffuse lighting), you can think of the dot product as a way of measuring the angle between the vectors. If the two vectors are perpendicular to each other, their dot product is zero; if they point away from each other, their dot product is negative. Specifically, the dot product of two unit vectors is the cosine of the angle between them. To see how to compute the dot product, here’s a snippet from our C++ vector library (see the appendix for a complete listing):

template <typename T>
struct Vector3 {
// ...
T Dot(const Vector3& v) const
return x * v.x + y * v.y + z * v.z;
// ...
T x, y, z;


Don’t confuse the dot product with the cross product! For one thing, cross products produce vectors, while dot products produce scalars.

With OpenGL ES 1.1, the math required for diffuse lighting is done for you behind the scenes; with 2.0, you have to do the math yourself in a shader. You’ll learn both methods later in the chapter.

The L vector in Diffuse coefficient can be computed like this:

In practice, you can often pretend that the light is so far away that all vertices are at the origin. The previous equation then simplifies to the following:

When you apply this optimization, you’re said to be using an infinite light source. Taking each vertex position into account is slower but more accurate; this is a positional light source.

3. Give It a Shine with Specular

Diffuse lighting is not affected by the position of the camera; the diffuse brightness of a fixed point stays the same, no matter which direction you observe it from. This is in contrast to specular lighting, which moves the area of brightness according to your eye position, as shown in Figure 3. Specular lighting mimics the shiny highlight seen on polished surfaces. Hold a shiny apple in front of you, and shift your head to the left and right; you’ll see that the apple’s shiny spot moves with you. Specular is more costly to compute than diffuse because it uses exponentiation to compute falloff. You choose the exponent according to how you want the material to look; the higher the exponent, the shinier the model.

Figure 3. Specular lighting

The H vector in Figure 3 is called the half-angle because it divides the angle between the light and the camera in half. Much like diffuse lighting, the goal is to compute an intensity coefficient (in this case, sf) between 0 and 1. Specular lighting shows how to compute sf.

Specular lighting

In practice, you can often pretend that the viewer is infinitely far from the vertex, in which case the E vector is substituted with (0, 0, 1). This technique is called infinite viewer. When E is used, this is called local viewer.
  •  iPhone 3D Programming : Adding Depth and Realism - Surface Normals (part 2)
  •  iPhone 3D Programming : Adding Depth and Realism - Surface Normals (part 1)
  •  iPhone 3D Programming : Adding Depth and Realism - Filling the Wireframe with Triangles
  •  iPhone 3D Programming : Adding Depth and Realism - Creating and Using the Depth Buffer
  •  iPhone 3D Programming : Adding Depth and Realism - Examining the Depth Buffer
  •  iPhone 3D Programming : HelloCone with Fixed Function
  •  iPhone 3D Programming : Vector Beautification with C++
  •  jQuery 1.3 : An image carousel
  •  jQuery 1.3 : Headline rotator
  •  Silverlight : Print a Document
  •  Silverlight : Capture a Webcam
  •  Silverlight : Make Your Application Run out of the Browser
  •  Silverlight : Put Content into a 3D Perspective
  •  Silverlight : Response to Timer Events on the UI Thread
  •  Silverlight : Build a Download and Playback Progress Bar
  •  Silverlight : Play a Video
  •  C# 4.0 : Add a Static Constructor and Initialization
  •  C# 4.0 : Add a Constructor
  •  .NET Compact Framework : Font Selection
  •  .NET Compact Framework : Drawing Text
    Top 10
    Most Favorite Business Softwares – Feb 2013
    Maingear Nomad 15 – Don’t Judge A Gaming Laptop By Its Cover
    MSI GX60 Gaming Notebook - Great Looks And A Fast GPU
    OCUK Limited Edition P170EM - A Great Screen And Balanced Setup
    Samsung Series 5 550P5C-S03 Review - A Perfect Farewell To Windows 7
    Kobo Mini eReader Review
    Keep Kids Online Safely (Part 3)
    Keep Kids Online Safely (Part 2)
    Keep Kids Online Safely (Part 1)
    Nikon 24-85MM F3.5-4.5G ED-IF VR With Amazing Optical Performance
    Most View
    Troubleshooting Reference : Tablets & Smartphones
    iPhone 3D Programming : Adding Depth and Realism - Filling the Wireframe with Triangles
    Windows Vista : Migrating User State Data - Installing USMT, Understanding USMT Components
    Optimus 4X HD Battery Life Appears Unconvincing
    BlackBerry Java Application : Installing the Development Environment - downloading the Java Development Kit
    Introducing Windows Phone 7 Photo Features (part 2) - Using a Chooser to Open Photos & Saving Photos to the Phone
    iPhone 5 rumors fueled by new iPad released
    Freecom Silverstore 2-Drive NAS 2TB
    Communicate Between Two Machines on the Same Network (WCF)
    Group Test: Android Tablets – November 2012 (Part 2) - DisGo 9104, Samsung Galaxy Tab 27.0 Wi-Fi
    Microsoft Sues Comet For Pirating Windows
    Exposure 1010 CD Player And Integrated Amplifier
    Seagate Slim Portable – Thin Mobile Drive
    Beginer's Guide To Sports Photography (Part 2)
    Thunderbolt Storage (Part 1)
    Manage iOS with iCloud (Part 2)
    Best Of The Year 2012 (Part 1)
    ASP.NET AJAX : Partial Refreshes (part 1) - A Simple UpdatePanel Test
    Understanding and Using Windows Server 2008 R2 UNIX Integration Components (part 1)
    In Detail – Humax DTR-T1000