Total internal reflection

I’ve been stepping through old scene files that I made when working on the original version of DeluxeRender.  A few have rendered OK with some temporary snags here and there.  But this render showed that something was very broken.  I probably had this bad render a decade ago, and just never solved the issue.

The 3 spheres in back are concrete or paper (pure diffuse).  The 3 in front are arsenic glass in various colors.

FunScene3.1

Mysterious rendering bug related to refraction.

Especially damning are the black acne spots on the light source itself.  This tells us that it’s not just a dark contribution, but something illegal going on that cancels out other legal contributions.

Looking at the image above, see if you can decide which of the three glass spheres in front was the issue… (HINT: It’s the one spraying evil on the walls.)

I’m going to go into a bit more detail than you might want here since I don’t do software development full time and find this process a bit like puzzle solving.

First I made a small crop on the light source and found a black dot.

White dots good, black dots bad.

White dots good, black dots bad.

I printed information about every ray involved in the render of the black pixel.  As expected, there were NANs (not a number).  NANs happen when you do illegal things like the square root of a negative number, tearing tags off pillows, or parking in a red zone.

In a moment of trial and error hackery, I tried reversing normals for refraction, and got the following image.  Note the reflected caustic onto the pink sphere on the left.   It’s a nice accidental metal look!  But it isn’t accurate as metal either, as you can see from the misaligned light reflections in the ball bearings.

FunScene3.3

Are my normals reversed?

Some more detailed debug code showed that the NANs only appeared when leaving a refractive object.  Not when entering.

And as you might have gathered (ha! a rendering pun!) in the first image, the error seems to be focused (ha!  a rendering pun!) on the magenta glass sphere on the left.

The index of refraction I’m using here is 2.0.  The higher the number, the more it bends light when interfacing with air (at an index of about 1.0).  Diamond is about 2.4, but what I’m using is pretty close to Zircon’s 1.96.  Look, I’m not made of money.

A little of the light getting refracted is usually reflected back (the green rays in the next image).  But higher indexes of refraction can fully reflect light trying to get out, an event called total internal reflection.  This is the idea fiber optics is based on.  Computing the refracted ray in this case gets into imaginary numbers and NANs if you’re not considering total internal reflection.

Refraction and reflection. Image found on a bsa troop web site. Boy scouts are much more advanced these days.

Refraction and reflection. Image found on a bsa troop web site. Boy scouts are much more advanced these days.

But Light entering a sphere isn’t able to enter at an angle that will ever cause total internal reflection.  I spent a few days spinning on this problem because of that fact.

In the end, I found an intersection between the large sphere on the left and the small glass sphere on the left.  Because of that intersection, light can enter the sphere and get bounced almost any direction, including directions that cause total internal reflection.  After adding a check for this condition, the image is much cleaner.  A 13 year old bug finally squashed!

Total Internal Reflection

No more NANs.

Now is it strange that I think I like the image where glass accidentally rendered as metal even more than the correct one?

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *