Recent Announcements for Project 4
- Diffuse Lighting Fix
If you perform diffuse lighting on a red sphere, the hemisphere where
the
light is shining should appear to be a more well-lit red, instead of
white
(specular highlights are white). If diffuse lighting is not
looking
correct, try adding the color of the material as a multiplicative factor
to the diffuse calculation. You can do this by changing:
Color = summation( Kd * Ci *
(Li dot N) )
...to:
Color = summation( Kd * Cm *
Ci * (Li dot N) )
Kd is the diffuse coefficient, Cm is the color of the material, Ci is
the
color of the light i , Li is the unit light vector to light i, and N is
the unit normal.
- Shadow Ray Floating Point Errors
One issue with computing shadow rays is that you may get a false
intersection hit when you test a shadow ray. When you generate a
shadow
ray coming from, say, the surface of a sphere, and you test if the ray
intersects an object, floating point error may result in your code
computing an intersection for the very sphere you started at.
You'll notice this error if see surfaces that should be well-lit, but
they
are peppered with black dots of shadow. The floating point error
in the
shadow test causes some of the shadow rays to intersect with the sphere
itself even though they shouldn't, which then creates these black dots.
To fix this error, the most robust solution is to actually move the
shadow
ray out a little from the point of intersection along the direction of
the
ray, to get out of the range of floating point imprecision. For
instance,
if your original ray were:
r(t) = P0 + t * dir
...you can transform it to:
r'(t) = P1 + t * dir
...where...
P1 = P0 + EPSILON * dir
EPSILON = a very small,
positive float, like 0.001, (a global constant)
This floating point error applies not only to shadow rays, but also to
reflection and refraction rays, which will need to be similarly
moved by EPSILON along their directions.
- Ray Data Structure
Clearing up a point of confusion, the two fields of a ray struct in the
starter code are (point start, point end), which is really a point
followed by a direction. In other words,
point start - a POINT,
it is the point that the way starts at, w = 1.0
point end - a VECTOR,
it is the direction that the ray is pointing in, w = 0.0
- Correction to raytrace.pdf
In the pseudocode in raytrace.pdf (linked from the Project 4 website),
the
4th line on the second page reads:
spec := Ks[j] *
intensity(flec) * (r.V)^ns[j];
There are a few things wrong with this line. First, to clarify
what (r.V)
is, 'r' should be the unit
vector Ri, the reflection
of Li (the light
vector for light i) about the normal. 'V' is correct, meaning it
is the
unit viewer vector. Also, since Ri exists for each light, we
need
to sum
it over all lights.
Finally, the multiplcation sign between intensity(flec) and [the dot
product with a power]
should instead be an add sign. Since one of
these
terms calculatates global reflection color while the other term
calculates
local specular highlights and they are independent, we need an add
rather
than a multiply.
So, the corrected line should read:
spec := Ks[j] * (
intensity(flec) + summation_i { (Ri.V)^ns[j] } );
Also note that instead of (Ri.V),
you can use the half vector dotted
with
the normal, (Hi.N).
To get the right effects, you may also want
to break
the specular coefficient Ks[j]
down into two nonequal coefficients, one
multiplying the global reflection ray intensity only and the other
multiplying the sum of the specular highlights only.