Skip to main content

Critical Angle and Snell's Window

·731 words·4 mins

I had to draw some debug art because the rays were shooting wonky directions. In the end it was an issue of local transformations coming into play. No surprise there. I finally got the normals pointing in the correct direction in the above image by manually removing the rotation of the parent. Unforch using to_local() is translating the normal as well as rotating it and giving me nasty results.

At first, I thought they were going to the origin but that’s not quite right, is it?

I guess I don’t need to use to_local(). All I want to do is to transform the rotation of the normal from global space to local space. Instead of applying the rotation of the parent, I need to apply the rotation of all ancestors. Instead of normal.rotated(-rotation) just do normal.rotated(-global_rotation) and we’re there.

This is looking correct to me:

But this is not:

To help me reason about it, I want to know whether the angle θ should be larger or smaller when the ray enters the block of glass.

A refresher from last time:

From Wikipedia:

n = 1 for a vacuum n = 1.52 for window glass

n₁ ✗ sin θ₁ = n₂ ✗ sin θ₂

I’ll assume a vacuum for everything that’s not a block. So when a ray enters a block I get:

θ₂ = asin( sin(θ₁) / n₂ )

Or really, actually:

θ₂ = asin( sin(θ₁) ✗ n₁ / n₂ )

For vacuum to glass n₁ / n₂ is 1.52 and for glass to vacuum it’s 1/1.52.

Here’s what Desmos has to say:

So for vacuum to glass θ₂ will be bigger than θ₁ and vice versa, vice versa.

That’s definitely not what I was seeing but I fixed my code and we’re getting the correct output now:

Next problem. What’s going on here?

The angle between the first ray and its normal is so big that it casts the internal ray at 90°. After about 55px that ray collides with the same surface and casts another ray straight downwards.

What is the correct behaviour when a ray is hitting the surface at such a shallow angle (relative to the surface)? I learned about Total Internal Reflection… is this related to that?

Oh yikes, I’m backwards.

For vacuum to glass n₁ / n₂ is 1.52 and for glass to vacuum it’s 1/1.52.

That’s actually the opposite. Going from vacuum to glass I should be seeing a smaller θ.

I noticed it looking at a couple images on Wikipedia.

That second image shows the issue I’m having with the critical angle.

https://www.youtube.com/watch?v=NAaHPRsveJk&ab_channel=QuantumBoffin

The video shows me a couple things.

  1. I gotta get myself a laser optics toy set!
  2. Even when the light refracts, some of it is also reflected.
  3. The larger the value of θ, the more light that gets reflected rather than refracted.
  4. At the critical angle all the light actually gets reflected, it doesn’t travel along the surface as Snell’s Law would indicate.
  5. I should have a semi-circle piece.

A commenter pointed out that this effect can be observed underwater. Looking straight up, you can see through the water because the light hitting your eye enters the water with a low value of θ. However, other directions you’ll see a reflection of the underwater environment.

Here’s a great image from inspiredpencil.com:

That circle where you can see through the surface is called “Snell’s Window.”

So, what does that mean for this little optics game?

I haven’t implemented reflections at all yet so maybe don’t cast a child ray if we’re at or near the critical angle.

When I implement reflections, I’ll have to decide at what point I draw a reflected ray. At the critical angle or before? Should I have some sense of strength of the ray and draw more translucent rays when they’re weaker? Don’t draw them at all when they’re below a certain threshold?

How is this going to affect gameplay?

This information was certainly new to me and reckon it’ll be new to a lot of players. It’s not counter-intuitive or anything so I don’t think I need to justify it. But I’ll definitely have a simple level that can only be solved using TIR. And then after that it just opens up more possibilities so I think it’s a good thing. Maybe it’ll make level design a little trickier.

I love this stuff.