Intro

This post is one of those projects that grew over time. My original plan was to explore implementing interior mapping in ThreeJS using an idea that I had which would reduce the shader complexity by using a mathematical approach instead of relying on branching. When I got to the point where I was happy my approach would work, I was just about to start writing this post when the thought passed through my mind: “how can I do frosted glass windows”, and then when I implemented that I naturally wanted reflections to complete the set. As the environment map I originally used for the reflections was taken at night, I also wanted to play around with having lights that turn on and off inside the rooms.

As such this post covers the following:

  1. Branchless interior mapping
  2. Fresnel Reflections
  3. Frosted Glass
  4. Using a texture to simulate day/night cycles.

On this page, the demo shows a building that I made in Blender. If you drag across the model it should rotate. When rotating you’ll see that there’s different types of windows across the surface of the building. I figured having a whole building to play with would give me plenty of room to experiment with different ideas, my favourite being the hole on the back of the building since it’s a fun use of the effect.

If you look closely enough, you may notice that some of the rooms are spatially impossible and theoretically should overlap or even exceed the bounds of the building’s walls. Also if you look under the building, you’ll see that there’s no interior geometry. This is because the rooms aren’t real. Interior mapping creates the illusion of a room behind the windows by projecting a view ray into a cubemap. This effect was largely popularised by Insomniac’s Spiderman, but it has been used in games for a long while before that.

The coolest thing about interior mapping is that it’s extremely efficient. Rather than having to render a bunch of interior geometry which is likely to get occluded by the building’s walls, one large quad could represent the entire interior of a building. To demonstrate this, one side of the building has had its entire face set to use the window material. By making use of smart UV tiling, making an entire skyscraper would be possible with no additional overdraw.

Interior mapping is something that I implemented a few years ago in Unity but as mentioned above my original approach relied on branching. Whilst playing around with writing a raymarched voxel renderer (coming soon™), I realised the DDA line drawing algorithm I was using to find the distance to the next closest voxel cell should also work for interior mapping. From the position our view intersects the window’s surface, we can use the same theory to find which interior wall our view ray would go on to intersect. Realising this, I gave myself the challenge of re-implementing interior mapping without using any branching at all.

The next page will provide a breakdown of how the interior mapping works by demonstrating it on a quad as well as talking briefly about the secondary effects I’ve added.