iPhone 3D Programming : Adding Depth and Realism - Shaders Demystified

1/14/2011 2:35:29 PM
Before we add lighting to the ES 2.0 rendering engine of ModelViewer, let’s go over some shader fundamentals. What exactly is a shader? We mentioned that shaders are relatively small snippets of code that run on the graphics processor and that thousands of shader instances can execute simultaneously.

Let’s dissect the simple vertex shader that we’ve been using in our sample code so far, repeated here in Example 1.

Example 1. Simple.vert
attribute vec4 Position; 
attribute vec4 SourceColor;
varying vec4 DestinationColor;
uniform mat4 Projection;
uniform mat4 Modelview;

void main(void)
DestinationColor = SourceColor;
gl_Position = Projection * Modelview * Position;

The keywords attribute, uniform, and varying are storage qualifiers in GLSL. Table 1 summarizes the five storage qualifiers available in GLSL.

Table 1. GLSL storage qualifiers
QualifierMaximum permitted[4]Readable from VSWritable from VSReadable from FSWritable from FS
attribute8 vec4YesNoNoNo
uniform512 scalars (VS), 64 scalars (FS)YesNoYesNo
varying8 vec4NoYesYesNo

[4] Implementation-specific data; pertains only to the iPhone 3GS.

Figure 1 shows one way to visualize the flow of shader data. Be aware that this diagram is very simplified; for example, it does not include blocks for texture memory or program storage.

Figure 1. Shader-centric view of OpenGL (VS = vertex shader, FS = fragment shader)

The fragment shader we’ve been using so far is incredibly boring, as shown in Example 2.

Example 2. Boring fragment shader
varying lowp vec4 DestinationColor;

void main(void)
gl_FragColor = DestinationColor;

Perhaps the most interesting new concept here is the precision qualifier. Fragment shaders require a precision qualifier for all floating-point declarations. The valid qualifiers are lowp, mediump, and highp. The GLSL specification gives implementations some leeway in the underlying binary format that corresponds to each of these qualifiers; Table 2 shows specific details for the graphics processor in the iPhone 3GS.


An alternative to specifying precision in front of every type is to supply a default using the precision keyword. Vertex shaders implicitly have a default floating-point precision of highp. To create a similar default in your fragment shader, add precision highp float; to the top of your shader.

Table 2. Floating-point precision in third-generation devices
QualifierUnderlying typeRangeTypical usage
highp32-bit floating point[−9.999999×1096,+9.999999×1096]colors, normals
mediump16-bit floating point[–65520, +65520]texture coordinates
lowp10-bit fixed point[–2, +2]vertex positions, matrices

Also of interest in Example 4-13 is the gl_FragColor variable, which is a bit of a special case. It’s a variable that is built into the language itself and always refers to the color that gets applied to the framebuffer. The fragment shading language also defines the following built-in variables:


gl_FragData is an array of output colors that has only one element. This exists in OpenGL ES only for compatibility reasons; use gl_FragColor instead.


This is an input variable that contains window coordinates for the current fragment, which is useful for image processing.


Use this boolean input variable to implement two-sided lighting. Front faces are true; back faces are false.


This is an input texture coordinate that’s used only for point sprite rendering.

  •  Programming with DirectX : Transformation Demo
  •  Programming with DirectX : View Transformations
  •  Programming with DirectX : World Transformations
  •  Programming with DirectX : Projection Transformations
  •  iPhone 3D Programming : Adding Depth and Realism - Lighting Up (part 2)
  •  iPhone 3D Programming : Adding Depth and Realism - Lighting Up (part 1)
  •  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
    Top 10
    Windows Vista : Installing and Running Applications - Launching Applications
    Windows Vista : Installing and Running Applications - Applications and the Registry, Understanding Application Compatibility
    Windows Vista : Installing and Running Applications - Practicing Safe Setups
    Windows Server 2003 : Domain Name System - Command-Line Utilities
    Microsoft .NET : Design Principles and Patterns - From Principles to Patterns (part 2)
    Microsoft .NET : Design Principles and Patterns - From Principles to Patterns (part 1)
    Brother MFC-J4510DW - An Innovative All-In-One A3 Printer
    Computer Planet I7 Extreme Gaming PC
    All We Need To Know About Green Computing (Part 4)
    All We Need To Know About Green Computing (Part 3)
    Most View
    Managing Xen : Xen Domain Configuration Files
    Programming WCF Services : Queued Services - Transactions
    Alienware M17X - Best In Class Gaming Performance
    We Help You Find Your Ideal Smartphone (Part 4)
    Choosing The Right Parts For Your Build (Part 3) - Picking the right video card
    Homeplug Problems In A Factory Setting (Part 2)
    Guide To Upgrades With The Greatest Effects (Part 2)
    Microsoft ASP.NET 4 : Profiles - Understanding Profiles
    VMware Fusion 5 - Your Mac is Virtually a PC
    Running Windows 8 (part 2) - Power Plans, Sleep Modes, and Shutdown
    The Ultimate PC Security Toolbox (Part 1)
    The big test … Inter Core Power (Part 1) - Acer Aspire Ethos 8951G
    Windows Vista : Build Your Network (part 4) - Troubleshoot Wireless Networks
    Mac - That Syncing Feeling
    Macbook Air vs. Ultrabook Platform (Part 2)
    Find Yourself With Geolocation Technology (Part 3)
    The Complete Guide To Garageband (Part 1)
    Generation I (For Insecure)?
    Kingston SSDNow mS100 64GB - One Of The Cheapest SSDs Around
    You Can Master RAW (Part 4)