void testCosineHalfSphere() { Plot2D plot_down_z( output_path + "/cosine_half_sphere__down_z.png", plot_size, plot_size ); Plot2D plot_down_y( output_path + "/cosine_half_sphere__down_y.png", plot_size, plot_size ); Plot2D plot_rot( output_path + "/cosine_half_sphere__rot.png", plot_size, plot_size ); Transform xform = makeRotation( 0.5, Vector4( 1.0f, 1.0f, 1.0f ) ); Vector4 v, rot; for( auto i = 0; i < points_per_plot; i++ ) { rng.cosineUnitHalfSphere( v ); plot_down_z.addPoint( v.x, v.y ); plot_down_y.addPoint( v.x, v.z ); rot = mult( xform.fwd, v ); plot_rot.addPoint( rot.x, rot.y ); } }
DistributionSample Material::sampleCosineLobe( RandomNumberGenerator & rng, const RayIntersection & intersection ) const { DistributionSample sample; // FIXME: There must be a faster way // Generate an arbitrary direction to help us make a basis for tangent space. // The likelyhood that this is pointing in the same direction as the normal is very low. Vector4 elsewhere; rng.uniformVolumeUnitCube(elsewhere); Vector4 tangent = cross(elsewhere, intersection.normal).normalized(); Vector4 bitangent = cross(intersection.normal, tangent).normalized(); // Randomly generate a direction from a cosine-weighted pdf centered about the normal Vector4 R; rng.cosineUnitHalfSphere(R); sample.direction = R.x * tangent + R.y * bitangent + R.z * intersection.normal; sample.direction.makeDirection(); sample.pdf_sample = dot(sample.direction, intersection.normal) / M_PI; //sample.pdf_sample *= M_PI; // TEMP - FIXME - this shouldn't be here sample.pdf_sample *= 2.0 * M_PI; // TEMP - FIXME - this shouldn't be here return sample; }