 
 
 /**
- * Creates a uniformly random direction in the hemisphere defined by the normal  
+ * Creates a uniformly random direction in the hemisphere defined by the normal
  *
- * Based off the algorithm and code in 'Physically Based Rendering, 2nd Ed.' - Pharr & Humphreys
- * Chapter 13 - Example 13.6.1 - Pg. 664
+ * Based on http://www.rorydriscoll.com/2009/01/07/better-sampling/
  *
  * @param normal        The normal that defines the hemisphere
  * @param randState     The random state to use for internal random number generation        
  * @return              A uniformly random direction in the hemisphere
  */
-__device__ float3 CreateUniformDirectionInHemisphere(float3 normal, curandState *randState) {
-	// Create a random coordinate in spherical space
-	float z = curand_uniform(randState);
-	float r = sqrt(1.0f - z * z);
-	float phi = TWO_PI * curand_uniform(randState);
-	
+__device__ float3 CreateUniformDirectionInHemisphere(float3 normal, curandState *randState) {	
 	// Find an axis that is not parallel to normal
 	float3 majorAxis;
 	if (abs(normal.x) < INV_SQRT_THREE) { 

/**
 * Creates a random direction in the hemisphere defined by the normal, weighted by a cosine lobe  
 *
 * Based off the algorithm and code in 'Physically Based Rendering, 2nd Ed.' - Pharr & Humphreys
 * Chapter 13 - Example 13.6.2 & 13.63 - Pgs. 664 to 669
 *
 * @param normal        The normal that defines the hemisphere
 * @param randState     The random state to use for internal random number generation        
 * @return              A cosine weighted random direction in the hemisphere
 */
__device__ float3 CreateCosineWeightedDirectionInHemisphere(float3 normal, curandState *randState) {
	// Create a random coordinate in spherical space
	float theta = TWO_PI * curand_uniform(randState);
	float r = curand_uniform(randState);
	
	// The position in local space
	float x = r * cos(theta);
	float y = r * sin(theta);

	// Find an axis that is not parallel to normal
	float3 majorAxis;
	if (abs(normal.x) < INV_SQRT_THREE) { 

	float3 v = cross(normal, u);
	float3 w = normal;

	// Create a random coordinate in spherical space
	float z = curand_uniform(randState);
	float r = sqrt(1.0f - z * z);
    float phi = TWO_PI * curand_uniform(randState);
	float x = cos(phi) * r;
	float y = sin(phi) * r;

	// Transform from spherical coordinates to the cartesian coordinates space
	// we just defined above, then use the definition to transform to world space
