# Phong Modified BRDF Implementation

According to: https://www.cs.virginia.edu/~jdl/importance.doc

For a specular sample: (page 4 of the document) $$pdf(\theta_{i}) = \frac{n+1}{2\pi} \cos^n(a)$$

And this is how you choose an incoming direction according to a specular sample of the BRDF (page 4 of the document): $$\vec{w_{i}} = (\alpha, \phi) = (\arccos(\varepsilon_{1}^{ \frac{1}{n+1} }), \ \ 2\pi\varepsilon_{2})$$

But according to the figure on page 4, a specular sample has a BRDF favoring a direction which is highly dependent on the incoming ray, but the $\phi$ angle is decided by uniformly sampling a circle, disregarding completely the incoming direction, which to me makes no sense

Shouldn't the $\phi$ angle favor the specular direction, which is dependent on the incoming ray? Why we're not using at all the incoming ray to calculate the sampled direction which is supposedly sampling the brdf?

No matter where I look for it, I haven't seen an implementation using a BRDF which takes into account the incoming direction, which makes me think I've misunderstood the theory behind it

Lastly, assuming a standard backward path tracer, is this pseudocode the right way of computing the results?

color =  float3(1,1,1)
ray   =  getRayFromCamera()

for NUM_BOUNCES:
primitive = world.intersect(ray)

// assuming primitive is non null, I'm omitting the code where we sample a background
albedo           = primitive.albedo

// computeOutGoingRay will return a Ray and a PDF
outgoingRay, pdf = primitive.material.computeOutGoingRay(ray, normal, etc..)

// of the incoming radiance, how much is scattered along the new direction?
brdf             = primitive.brdf(outgoingRay, ray)

color = (color * albedo * brdf) / pdf

// assigning the new ray to keep our backward recursion
ray   = outGoingRay

• on a phong brdf, samples are generated in a space where the reflected direction is the z axis. thats where the dependence comes from Jan 26 '18 at 5:41
• Still, the phi angle is sampled over a circle uniformly instead of favoring the specular direction! This is the part I didn't get Jan 26 '18 at 11:41

Consider the following scheme that mimicks the generation of a sample for phong shading. where V is the viewer direction, N is the normal, R is the specular reflection direction and $S_i$ is some sample. This space (commonly called tangent space) uses the normal as one of its basis vectors. you can think of it as the 'Z axis'

Now, when we generate samples for Phong shading wo do not generate them in this space.

Rather, we use a different reference system where the Specular reflection direction is the 'z axis', thus, our angle $\theta$ is the angle between the reflected direction and the sample direction, and the angle $\phi$ is the angle between some $S_{ix}$ that is the projection of our sample direction onto the plane perpendicular to $R$ and some arbitrary but constant vector perpendicular to our reflected direction

$\phi$ is a number that is sampled uniformly in the range $(0,2\pi)$ this means that rays will be generated around the reflected direction with no bias towards any particular direction.

Generated rays will, however, be biased to have a direction close to $R$ due to the way that $\theta$ is sampled.

When we generate rays in a backwards pathtracer we use the view direction to get the directions where the light is likely to come from, instead of throwing light around and seeing where it falls. The later technique is closer to photon mapping.

• Can't thank you enough, as a side question: after computing a sample according to this model, the resulting radiance should be divided by the pdf specified in the first formula I've posted? Jan 26 '18 at 22:56
• it should be multiplied by the brdf and divided by the pdf. those usually cancel each other out so it is often not necesary Jan 26 '18 at 23:11