FZR in Uffizi (and thin dielectrics)

December 2nd, 2006 by Bramz

I’ve reproduced the older FZR render using the Ashikhmin & Shirley BSDF and the Uffizi Gallery light probe. For the glass of the windows and the head lights, I’ve implemented a new material called ThinDielectric that acts as a thin (but not very) pane of glass. Given an inner refraction index and transparency factor for the medium, it simulates multiple reflections and transmissions due to the bouncing of the light inside the pane. Maybe I will write it more properly some day, but here’s how it goes in a nutshell:

  • R = r \left(1 + \frac{\left(1 \minus r\right)^2 t^2}{1 – r^2 t^2}\right)
  • T = \frac{\left(1 – r\right)^2 t^2}{1 – r^2 t^2}


  • R and T the resulting reflectance and transmittance \left(R + T < 1\right)
  • r is your usual fresnel reflectance
  • t = \tau ^ {\frac 1 {\cos \theta_t} is the transmittance of the medium using Beer’s law where \tau is the transparency of the medium and \cos \theta_t is the cosine of the angle of the refracted rays inside the material

FZR with PHD-Motorsports skin in Uffizi gallery

Model by Live for Speed, light probe by Paul Debevec, custom skin by PHD-Motorsports.

update: this render is also featured in the #flipcode gallery.

update: Nicholas “Ono-Sendai” Chapman of the Indigo Renderer has pointed out that Radiance is using a very similar BSDF for their glass material. This is not so surprising, since it’s a very simple extension of the Fresnel equations. The only difference is the distinction between TE and TM waves, which is more correct than what I’m currently doing.

update: Leonhard Gruenschloss noticed a few typos in my formulas (see comments). I’ve corrected them now Thanks Leonhard! (20 feb. 2007)

5 Responses to “FZR in Uffizi (and thin dielectrics)”

  1. Reedbeta Says:

    This thin dielectrics concept is really interesting. Is it a big performance win over simulating a pane of glass with two actual surfaces? Also, how did you derive those equations?

    I’ve thought about doing something along similiar lines for objects like paper lampshades. They’re very thin but scatter light so much that you need full volumetric multiple-scattering to simulate them – super slow! But there’s probably a way to produce a material like this, but based on diffuse reflection and transmission instead of specular, which could approximate the paper translucency effect.

  2. bramz Says:

    It’s a performance win because you only have one intersection (in contrast to many) and thus also only one shader evaluation. It’s also a stability win because you will get less troubled with tolerances and other numerical joys. But these are only nice side effects. The main reason why I’ve done it this way is because the window was modeled as only one surface. So, unless I wanted to tweak the model, I simply had no other choice than using a “collapsed pane”.

    The derivation is actually very simply. On a piece of paper, you draw a pane of glass with two interfaces, an incident light ray that reflects a first time on the surface and also enters the pane. There, it bounces an “infinite” times between both interfaces, each time transmitting some energy through the interface. You get an infinite number of rays leaving the pane on the incident side, and also an infinite number leaving on the opposite side. For each of them, you calculate the fraction of the incident energy attributed to it. Finally, for each side, you lump together all contributions and thanks to some nice mathematical properties, you can simplify it to the formulas above.

    The trick used is of course that all the rays leaving the pane appear to originate in the same point, but of course they do not really so. If you can make the same approximation, then yes, you would be able to produce such a material. But somehow, I suspect it won’t be entirely so.


  3. Leonhard Gruenschloss Says:

    Thanks a lot for this very interesting blog!

    Regarding the thin plate formula: Isn’t the Radiance formula different, even when setting F_TE = F_TM = r? Then the formula in http://radsite.lbl.gov/radiance/refer/materials.pdf simplifies to

    T = (1 – r)² / (1 – r² * t²),
    R = r * (1 + (1 – 2*r) * t²) / (1 – r² * t²),

    whereas you propose

    T = (1 – r)² * t / (1 – r² * t²),
    R = r * (1 + (1 – r)² * t²) / (1 – r² * t²)
    = r * (1 + (1 – 2*r + r²) * t²) / (1 – r² * t²).

    And probably you meant
    t = pow(transparency, 1 / cos_t)
    as in your post on flipcode.

  4. Leonhard Gruenschloss Says:

    Oh, I overlooked a multiplication in the radiance document.
    The correct version for the transmittance is
    T = (1 – r)² * t / (1 – r² * t²),
    so that’s equivalent to your approach.

  5. bramz Says:

    Hi Leonhard,

    Thanks for your response.

    You’re right, I’ve made a few typos in my post. Thought the error is in R rather than in T. I’ve put my round brackets in the wrong place. It should read
    R = r * (1 + (1 – r)² * t² / (1 – r² * t²))
    instead of
    R = r * (1 + (1 – r)² * t²) / (1 – r² * t²)

    Also, you’ve correctly pointed out that it is
    t = pow(transparency, 1 / cos_t)
    rather than
    t = pow(transparency, cos_t)

    I’ve corrected both in the original post. Thanks for pointing them out!