Ray-tracing Refraction – Floating Point Error
To implement refraction in ray-tracing rendering, we can simply use the refraction equation:
sin(theta1)/sin(theta2) = n2/n1
To compute sin(theta1), simply:
sin(theta1) = sqrt(1-cos(theta1) * cos(theta1));
where v1 is the incomming ray direction, and N is the surface normal.
However, there may be trouble when this implementation runs in computer. In C++, since we can’t avoid floating point error, when v1 is almost perpendicular to the surface, that is, v1 and N almost the same (or they just be the same), cos(theta1) could slightly greater than 1 (something like 1.00001). Then, this result would cause:
1-cos(theta1) * cos(theta1) < 0
And would return invalid result if . So that becomes a invalid value. Eventually, all the computation mess up. The pixel we want to shade becomes an error pixel.
To avoid this, simply put a check routine like:
cos(theta1) = min(1.0f, v1.dot(N))
Never trust floating point number!!