Depth of Field and Reflections

When you stand in front of a mirror, your reflection appears to be "behind" the mirror, not superimposed upon it like a poster or a TV image is. It has the same kind of depth as you would see if the mirror were simply a window looking at another room with another person in it. The same goes for any mirrored surface -- the reflection appears underneath the surface, and has its own apparent depth.

However, all current computer renderers only calculate the Z-buffer to the *reflecting surface*. As a result, all Z-buffer-based depth of field simulations will therefore blur not to the reflection, but to the surface of the mirror -- as if the reflection were simply a surface coloration. This is normally not an issue for convex surfaces, since the apparent error is small, but can cause significant problems with flat mirrors are nearby but reflecting objects that are far away.

The only way around that would be to have multiple Z-values for each pixel, a solution which gets expensive in terms of space and render time rather quickly, I bet.

However, I devised a brute-force solution, based on the methods used by "spinning lights", to achieve a "spinning camera" effect. Since this method is a "brute-force" simulation method, it will work properly with "curved" mirrors, flat ones, "dusty" mirrors etc. It will also work for objects behind transparent polygons, which suffer from the same impediment.

1. X-DOF

This image below is rendered using X-DOF, a pixel filter that uses the zbuffer. Observe that the reflection of the barred window is blurred with the near objects, even though in reality it would be sharp.

Here is the same image, but focussed nearby. Notice that the barred window reflection is now in sharp relief instead of being blurry like the original.


I had originally believed that the LightWave built-in DOF effect was based on a more brute-force real-world simulation of the lens area, but in fact it too is based on the Z-buffer.


So, I decided to make use of a "spinning camera", based on the same principles as spinning lights. Here are my results below.

But How?

So how is this done?

Here's a scene with only the camera assembly in it. Here's a sample animation (you need divx and LW 7.x)from the above scene that spawned this idea.

And here's the verbal explanation:

The scene consists of four nulls. The root null is the Assemblypointer; this is what you move and rotate just like the original Camera to effect pans, dollies etc.

The second null, parented to the Assemblypointer is the Spinner. This is the moving null that is spun to give us our sampling pattern, in conjunction with the Motion Blur setting. This null rotates on its bank axis by an integer multiple of 360 degrees to derive the overall sampling pattern. Use a keyframe at 0, keyframe at 1 and Offset Repeat, both directions.

The third null in the hierarchy is the Camcarrier null (parented to the Spinner). It must be keyframed in two ways: First, it needs to be given the same bank envelope as the Spinner, but negative, so that it cancels out the rotation. Second, its Y distance from the Spinner forms the effective radius of the "lens" or sampling pattern.

The fourth null is the Camtarget. This is used to focus the assembly. Target the Camera to it. If you want it to be a focus control only, parent Camtarget to the Assemblypointer and lock its X and Y channels to 0. Keyframe it along the Z axis to focus. If you want to use it as an independent target, leave it uparented from the Assemblypointer, and target the Assemblypointer to it also (so that the sampling plane remains perpendicular to the line of sight.) The Assembly will autofocus to it automatically. Without the Camtarget, the Assembly would be focussed at infinity.

Using a simple 360 circle works for less extreme DOF, but as in my examples above, ringlike "iris" patterns will result if pushed too far. To mitigate this, multiply the Spinner (and the Camcarrier's opposing envelope) by the number of rings you wish to draw. My sample scene uses a 2x spin; the Spinner/Camcarrier are spun 2x360=720 degrees per frame. Then, key the Camcarrier on its Y axis using stepped keys to spend the first half of the frame (one complete spin) at half-radius, and the second half at full radius. This creates two ring blur patterns, the half-size one filling in the middle of the full-size one.

With that arrangement, simply set the Motion Blur length at 50% to place all nine samples in the outer ring, or set it to 100% to spread them between both rings. My sample animation has Motion Blur set to High and splits the 17 samples between two rings.

For extreme situations, you can do the same thing with 3 or even 4 spins and keyframe the Camcarrier on its Y axis to distribute the spins as you see fit. You could also keyframe the Camcarrier to try to give a specific iris shape to the blur, but I have not tried this.

Since this is a brute-force sampling approximation method, it will work with reflections, refractions and any other effect that works without DOF. IT is not Z-buffer based and is therefore immune to any problems or limitations related to the Z-buffer.

This concept will work for LightWave 5.x also.

Jim May/Court Jester Creations.

Contact The Jester

Your Name: *
Your E-mail: *
Comments/Questions: *

(Fields with an asterix * are required)