I E

Sunstone dev log 24: physically-based camera (round 2)

Finally back to the code! I’ve spent about a week wrapping my head around the theory required to use physical units in rendering. Now I have a decent grasp of what I need to build.

I thought I could introduce camera exposure with a single render pass, but it doesn’t seem like such a good idea now that I know the details. The main render pass uses MSAA, so its fragment shader writes to a multi-sampled colour attachment, which is resolved into a single-sample image at the end of the render pass. To do camera exposure in a single pass, I’d have to write radiance values to a multi-sampled image to be read by a compute shader to produce an average luminance for use in the next frame. At 4x MSAA, that’s a 4x memory overhead (compared to a single-sample image) to store an image that I just want to average. To avoid that memory overhead, the main render pass resolves radiance to a single-sample HDR image, and a second post-processing render pass performs camera exposure on the HDR image to produce a LDR image for presentation.

Fragment ray angles

In the post-processing fragment shader I need cos⁡θF\cos\theta_F where θF\theta_F is the angle between the optical axis and a ray from the camera origin to the fragment. I was able to derive a formula for cos⁡θF\cos\theta_F in terms of fragment coordinates:

1((xs−Ws2)2+(yx−Hs2)2)4Hs2tan⁡2θy2+1 \frac{1} {\sqrt{((x_s - \frac{W_s}{2})^2 + (y_x - \frac{H_s}{2})^2)\frac{4}{H^2_s}\tan^2\frac{\theta_y}{2} + 1}}

where:

Here’s my derivation:

Vignetting

cos⁡θF\cos\theta_F is used to weight the radiant exposure by cos⁡4θF\cos^4\theta_F, which causes vignetting. The vignetting was subtle and I wasn’t sure that it worked:

Before
After

I captured before and after images and used GIMP’s “difference” blend mode to check whether there actually was a difference. That gave an image where black represented “no difference” and dark colours represented small differences. I found that hard to read, so I took the difference between that image and white:

The center of the image is white (no difference), and gets darker toward the edges (difference increases). Looks good to me.

Next steps

← Sunstone dev log 23: colour 'n' stuff Newest