     float r2 = random(rsi++);
 
     float a = M_2_PI * r1;
-    float b = sqrt(1.0 - r2 * r2);
-
-    pdf = 1.0 / M_2_PI;  // uniform sampling
-
-    return normalize(vec3(cos(a) * b, sin(a) * b, r2));
+    float b = sqrt(1.0 - r2);
+
+    float z = sqrt(r2);
+
+    pdf = z / M_PI;
+
+    return normalize(vec3(cos(a) * b, sin(a) * b, z));
 }
 
 /**

    vec3 sum = vec3(0, 0, 0);

    cell_index.x = 0.5;
    for (int i = 0; i >= 0; ++i) {

        if (cell_index.x >= degree) { break; }

        cell_index.y = 0.5;
        for (int j = 0; j >= 0; ++j) {

            if (cell_index.y >= degree) { break; }

/**
 * Bounces a ray off a lambertian surface.
 *
 * @param      rsi   Random seed offset.
 * @param[out] pdf   Probability of chosen direction.
 *
 * @details
 *      This implementation draws from a cosine-weighted distribution.
 */
vec3 bounce_lambert(inout int rsi, out float pdf) {

