Skip to content

Chapter 7, 8, 9 floating point intersection error #137

@vchizhov

Description

@vchizhov

There is a small issue with the materials introduced in chapters 7, 8 and 9 (lambertian, metal, dielectric). Due to floating point error, it may happen that the intersection of a ray with some geometry (in this case a sphere) may be "on the wrong side" (let the ideal intersection be at t0, however due to precision error let one get t1: t1>t0, then r_in.point_at_parameter(t1) would be "on the wrong side"). That means that when we try to scatter a ray, it will start inside of the sphere resulting in self-intersection and a black pixel contribution in the final image (akin to shadow acne). This is valid for both lambertian and metal materials, it is especially obvious for perfect mirror materials (fuzz==0.0) when they are introduced in chapter 8 since we get black pixels where we're not supposed to. To mitigate this issue, one can define epsilon = 0.01 (depending on the scale of your geometry this value may have to be smaller or larger) and when returning the scattered ray, make it have origin not rec.p, but rather rec.p + epsilon*normal. Which leads me to another issue - if an object is intersected "from inside", the wrong normal is used for lambertian scattering and reflection (fortunately the right normal is used for refraction). To fix this, use this normal for lambertian scattering, reflection and refraction: normal = dot(r_in,rec.normal)<0.0f? rec.normal : -rec.normal. For refraction the scattered ray should rather start from rec.p - epsilon*normal (we want to be on the opposite side, to avoid self-intersection).
Another thing that may look like a mistake is: schlick(cosine, ref_idx) since based on the definition it should be schlick(cosine, ni_over_nt). However, in this case it is lucky that schlick(cosine, 1.0/ni_over_nt) == schlick(cosine, ni_over_nt) since ((1-ni_over_nt)/(1+ni_over_nt))^2 == ((1-1/ni_over_nt)/(1+1/ni_over_nt))^2.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions