MULTIMEDIA

# iPhone 3D Programming : Adding Shaders to ModelViewer (part 2)

1/14/2011 2:39:55 PM
##### #### 2. Per-Pixel Lighting When a model has coarse tessellation, performing the lighting calculations at the vertex level can result in the loss of specular highlights and other detail, as shown in Figure 1.Figure 1. Tessellation and lighting (from left to right: infinite tessellation, vertex lighting, and pixel lighting)One technique to counteract this unattractive effect is per-pixel lighting; this is when most (or all) of the lighting algorithm takes place in the fragment shader.Warning:Shifting work from the vertex shader to the pixel shader can often be detrimental to performance. I encourage you to experiment with performance before you commit to a specific technique.The vertex shader becomes vastly simplified, as shown in Example 6. It simply passes the diffuse color and eye-space normal to the fragment shader.Example 6. PixelLighting.vert`attribute vec4 Position;attribute vec3 Normal;attribute vec3 DiffuseMaterial;uniform mat4 Projection;uniform mat4 Modelview;uniform mat3 NormalMatrix;varying vec3 EyespaceNormal;varying vec3 Diffuse;void main(void){ EyespaceNormal = NormalMatrix * Normal; Diffuse = DiffuseMaterial; gl_Position = Projection * Modelview * Position;}` The fragment shader now performs the burden of the lighting math, as shown in Example 7. The main distinction it has from its per-vertex counterpart  is the presence of precision specifiers throughout. We’re using lowp for colors, mediump for the varying normal, and highp for the internal math.Example 7. PixelLighting.frag`varying mediump vec3 EyespaceNormal;varying lowp vec3 Diffuse;uniform highp vec3 LightPosition;uniform highp vec3 AmbientMaterial;uniform highp vec3 SpecularMaterial;uniform highp float Shininess;void main(void){ highp vec3 N = normalize(EyespaceNormal); highp vec3 L = normalize(LightPosition); highp vec3 E = vec3(0, 0, 1); highp vec3 H = normalize(L + E); highp float df = max(0.0, dot(N, L)); highp float sf = max(0.0, dot(N, H)); sf = pow(sf, Shininess); lowp vec3 color = AmbientMaterial + df * Diffuse + sf * SpecularMaterial; gl_FragColor = vec4(color, 1);} ` Note:To try these, you can replace the contents of your existing .vert and .frag files. Just be sure not to delete the first line with STRINGIFY or the last line with the closing parenthesis and semicolon.Shifting work from the vertex shader to the fragment shader was simple enough, but watch out: we’re dealing with the normal vector in a sloppy way. OpenGL performs linear interpolation on each component of each varying.  Pragmatically speaking, simply renormalizing the incoming vector is often good enough. #### 3. Toon Shading Mimicking the built-in lighting functionality in ES 1.1 gave us a fairly painless segue to the world of GLSL. We could continue mimicking more and more ES 1.1 features, but that would get tiresome. After all, we’re upgrading to ES 2.0 to enable new effects, right? Let’s leverage shaders to create a simple effect that would otherwise be difficult (if not impossible) to achieve with ES 1.1.Toon shading (sometimes cel shading) achieves a cartoony effect by limiting gradients to two or three distinct colors, as shown in Figure 2.Figure 2. Toon shadingAssuming you’re already using per-pixel lighting, achieving this is actually incredibly simple; just add the bold lines in Example 8.Example 8. ToonShading.frag`varying mediump vec3 EyespaceNormal;varying lowp vec3 Diffuse;uniform highp vec3 LightPosition;uniform highp vec3 AmbientMaterial;uniform highp vec3 SpecularMaterial;uniform highp float Shininess;void main(void){ highp vec3 N = normalize(EyespaceNormal); highp vec3 L = normalize(LightPosition); highp vec3 E = vec3(0, 0, 1); highp vec3 H = normalize(L + E); highp float df = max(0.0, dot(N, L)); highp float sf = max(0.0, dot(N, H)); sf = pow(sf, Shininess); if (df < 0.1) df = 0.0; else if (df < 0.3) df = 0.3; else if (df < 0.6) df = 0.6; else df = 1.0; sf = step(0.5, sf); lowp vec3 color = AmbientMaterial + df * Diffuse + sf * SpecularMaterial; gl_FragColor = vec4(color, 1);} `
 Other

 Most View
 -  Rosewill Launches Armor Evolution Mid-Tower Case
 -  Keep Kids Online Safely (Part 1)
 -  Extending the Real-Time Communications Functionality of Exchange Server 2007 : Installing OCS 2007 (part 2)
 -  Buyer’s Guide: e-Readers That Fits Your Needs Best (Part 1)
 -  Thunderbolt External Drives (Part 1)
 -  Apple iPhone 5 - Fails To Return To The Top (Part 2)
 -  Syncing And Streaming (Part 2) - Apple TV, The remote app
 -  Preparing Your Windows 8 PC : Adding Devices in Windows 8 (part 1) - Viewing Installed Devices
 -  Group Test: Free Office Suites (Part 3) - LibreOffice
 -  Turn An Old Computer Into A Server Using Ubuntu (Part 2)
 Top 10
 -  The NZXT Kraken X40 Compact Liquid Cooler Review (Part 3)
 -  The NZXT Kraken X40 Compact Liquid Cooler Review (Part 2)
 -  T-Mobile’s Samsung Galaxy Note II Review (Part 6)
 -  T-Mobile’s Samsung Galaxy Note II Review (Part 5)
 -  T-Mobile’s Samsung Galaxy Note II Review (Part 4)
 -  T-Mobile’s Samsung Galaxy Note II Review (Part 3)
 -  T-Mobile’s Samsung Galaxy Note II Review (Part 2)
 -  T-Mobile’s Samsung Galaxy Note II Review (Part 1)
 -  Sony Cybershot DSC-TF1 - Affordable Water-Resistant Camera
 -  Buffalo MiniStation Slim 500GB External Hard Drive