     bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
 	return float(bits) * 2.3283064365386963e-10; // / 0x100000000
 }
+
+// hammersley2d describes a sequence of points in the 2d unit square [0,1)^2
+// that can be used for quasi Monte Carlo integration
 vec2 hammersley2d(int i, int N) {
     return vec2(float(i)/float(N), radicalInverse_VdC(uint(i)));
  }
 
-
-vec3 getImportanceSampleDirection(vec3 normal, float sinTheta, float cosTheta, float phi)
-{
-	vec3 H = normalize(vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta));
-
+// Hemisphere Sample
+
+// TBN generates a tangent bitangent normal coordinate frame from the normal
+// (the normal must be normalized)
+mat3 generateTBN(vec3 normal)
+{
     vec3 bitangent = vec3(0.0, 1.0, 0.0);
 
 	// Eliminates singularities.

    vec3 tangent = cross(bitangent, normal);
    bitangent = cross(normal, tangent);

	return normalize(tangent * H.x + bitangent * H.y + normal * H.z);
}

// https://github.com/google/filament/blob/master/shaders/src/brdf.fs#L136

}

// Hammersley Points on the Hemisphere
// CC BY 3.0 (Holger Dammertz)
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
// with adapted interface
float radicalInverse_VdC(uint bits)
{
    bits = (bits << 16u) | (bits >> 16u);
