   return rgbaFloatToInt(rgba);
 }
 
-__device__ float4 phong(const float4& classification, const float3& pos,
-                        const float3& L, const float3& H,
-                        const float3& Ka, const float3& Kd, const float3& Ks,
-                        const float shininess)
+__device__ float4 blinnPhong(const float4& classification, const float3& pos,
+                                     const float3& L, const float3& H,
+                                     const float3& Ka, const float3& Kd, const float3& Ks,
+                                     const float shininess,
+                                     const float3* normal = NULL)
 {
   float3 N;
   float3 sample1;

  float maxIntensity = 0.0f;
  float minIntensity = FLT_MAX;

  for (int i=0; i<maxSteps; ++i)
  {
    // Test for clipping.
    if ((
        (clipSphere && (t >= tsnear) && (t <= tsfar)) // Sphere.
     || (clipPlane && (((t <= tpnear) && (nddot >= 0.0f))
         || ((t >= tpnear) && (nddot < 0.0f)))) // Plane.
    ))
    {
      t += tstep;
      if (t > tfar)
      {

  sample2.z = volume(pos + make_float3(0.0f, 0.0f, DELTA));

  N = normalize(sample2 - sample1);

  if (normal != NULL)
  {
    // Interpolate gradient with normal from clip object (based on opacity).
    N = (*normal * classification.w) + (N * (1.0f - classification.w));
    N = normalize(N);
  }

  const float diffuse = fabsf(dot(L, N));
  const float specular = powf(dot(H, N), shininess);

