1
votes

I'm writing a ray tracer for iPad. Now I'm trying to add glossy reflection to an object. How do I implement it? I read some documentation online:

http://www.cs.cmu.edu/afs/cs/academic/class/15462-s09/www/lec/13/lec13.pdf http://www.cs.cornell.edu/courses/cs4620/2012fa/lectures/37raytracing.pdf

If I understood correctly instead of trace a single ray as for standard reflection I have to trace n ray in a random direction. How do I get this random direction for each ray? How do I generate these samples?

1
Anybody could help me?Fabrizio Duroni

1 Answers

5
votes
  • Specular reflection means that the angle between the incoming direction and the surface normal is equal to the angle between the outgoing direction and the surface normal.
  • Diffuse reflection means that the angle of the outgoing direction is randomly & evenly distributed about the surface normal's hemisphere.
  • You could think of glossy reflection as being the spectrum between these two extremes, where the location on that spectrum (or amount of gloss) is defined by a "glossiness" factor that could range from 0 to 1.
  • For diffuse or glossy reflection, you need to be able to randomly generate a ray from the distribution of possible reflection directions, and then follow it.
  • Then, take many samples and average the result.
  • So, for glossy reflection, the key is that the distribution of reflected rays is centered about the specular direction. The wider the distribution of rays, the more the gloss is diffused. an example

I would start by writing the following helper methods, in order:

// get a random point on the surface of a unit sphere
public Vector getRandomPointOnUnitSphere(); 

// get a Ray (with origin and direction) that points towards a 
// random location on the unit hemisphere defined by the given normal
public Ray getRandomRayInHemisphere(Normal n); 

// you probably already have something like this
public Ray getSpecularReflectedRayInHemisphere(Normal n, Ray incomingRay);

// get a Ray whose direction is perturbed by a random amount (up to the
// glossiness factor) from the specular reflection direction
public Ray getGlossyReflectedRayInHemisphere(Normal n, Ray incomingRay, double glossiness);

Once you get this working, you may want to rework your implementation to be in terms of actual BRDF objects, which will organize the logic somewhat and help you down the line if you want to extend your tracer to support refraction.