So my last entry of almost two months ago left on a note about light scattering, and this entry, which I'm sure you've all been waiting for with bated breath, will address this question at last, among others. I haven't been writing much code lately, due to time issues and - mostly - procrastination, however I had a lot of time to think.
I think I've succeeded in creating a sound conceptual framework based on relatively simple physical theories which should be able to model essentially everything non-magnetic/quantum/relativistic, from basic reflection to complicated cloud scattering. The basic idea is that any light-matter interaction can be modelled through only four essential processes:
Or STAR for short (yes, I rearranged them just to make this pun). However, that isn't all - each of these interactions can be studied independently.
If you've been doing computer graphics, you probably know reflection
well, through the use of BRDF's, which are reflectance distributions used to describe where light is going to get reflected from a surface. In the STAR framework, none of this exists. Reflection is described purely by the Fresnel equations, modulated by a surface distribution. In essence, a variant of Cook-Torrance.
This is because this model is really the only physically correct one, as Fresnel reflection must occur any time a light ray crosses a medium boundary (so all we need is to make this medium boundary more or less smooth, depending on how rough you want your surface to be, which can be done statistically with a microfacet distribution coupled with a self-shadowing term - or you can add microscopic triangles to your geometry for complete control, but that's not very practical).Transmission
is easy, as the Fresnel equations handle transmission at the same time, so no extra complexity there. This includes total internal reflection, by the way.Absorption
is described by the Beer-Lambert law, which states that the intensity of radiation through some medium decreases exponentially with distance travelled, depending on the medium's absorption (or extinction) coefficient, and density (this assumes a homogeneous medium, but you can use numerical integration to handle local density fluctuations). The simplest real-life example of this is red ink - inside its bottle, it appears black, because light must travel through many cm of ink before reaching your eyes and most of it gets absorbed. But as soon as you put the ink on paper, it appears deep red, as now light only travels half a mm or so inside.
can occur in any impure medium, whenever a light ray encounters a particle different from the medium surrounding it (for instance, a dust particle in the atmosphere, or an air bubble in milk). When this happens, the light ray is scattered in any direction (potentially back where it came from) depending on the medium's phase function, which is really just like a BRDF, but for scattering. Those phase functions are typically much more complicated than BRDF's depending on the size of the particle, as they must often consider interference effects. For instance, the phase function for a 10μm silver particle in air is (for red light, on a logarithmic scale):
As you can see, most of the incident light (at 0 degrees) is scattered backwards, but some is randomly scattered in every direction. The wavy nature of the phase function is due to interference between light rays (which are getting reflected back and forth inside the silver particle). This plot was made with the MiePlot software.
Scattering and absorption are generally simulated together, just as reflection and transmission are. So really, there are only two different interactions to consider: surface interactions (reflection & transmission -> Fresnel Equations), and volume interactions (scattering & absorption -> Phase Function). That's it.
When it comes to light rays, we really don't need the ray formulation of light anymore and we can consider them waves for all intents and purposes. That means that our light waves have a frequency (which is constant), a wavelength, and a phase (which varies with time and with interactions with matter). Therefore, we can model any physical phenomenon which uses those quantities, in particular diffraction, and interference, which is responsible for a wide range of effects, such as... mirrors! Your mirror uses a reflective coating based on the concept of interference:
A similar principle applies to anti-reflective coatings (the idea is to make the reflected rays interfere destructively with each other such that only the transmitted rays remain). Let us see how STAR applies to some common materials found in the real world:Hard wood:
- rough surface
- very high absorption (which stops transmitted rays)
- no visible scattering since the absorption coefficient is so highMarble:
- smooth surface
- low absorption, enough to make a thin marble layer translucent (e.g. not opaque, but not transparent either)
- high backscattering (this is the famous subsurface scattering phenomenon)Clear atmosphere:
- no surface
- extremely low absorption (although this depends on height)
- generally forward scattering, but mostly for blue wavelengths (this is why mountains in the distance appear blue/gray)Pure glass:
- ordinary dieletric surface (reflection/transmission as usual)
- absorption zero, or very very low
- no scatteringReflective object:
- multiple surfaces to enhance reflection, as shown in the mirror diagram above
- extremely high absorption (the object is opaque)
- no visible scatteringSoap bubble:
- multiple surfaces (the layers go air || soap || water || soap || air)
- no absorption, as the soap/water layers are extremely thin
- no visible scattering for the same reason
- strong interference effects (thin film interference) responsible for the colorful aspect of soap bubbles
And so on.. which is much larger array of materials than what can be represented with traditional approaches.
At this point, you're probably thinking, "cool, but
does it blend
how long does it take to render something like that", which is a fair remark, and I suspect it will take quite long to render complicated stuff like multiple scattering. On the other hand, the simplicity of the framework makes implementation easier, especially on limited platforms such as the GPU: there are few "moving parts" and the only hard thing is implementing diffraction, which isn't even important for most scenes in contrast to interference - even complex phase functions can be conveniently fitted by analytical models, for instance the mean cosine distribution, which is kind of like Blinn-Phong, but for scattering.
Sure, you get a few more intersection tests with your geometry when it comes to multiple surface layers, but you're going to be doing that a lot regardless if you want to accurately model scattering (approximations only get you so far), so you might as well get correct reflections too. One important thing to note is that adding extra layers to a mesh does not
add any memory overhead, since the layer has the exact same geometry as the mesh, except slightly enlarged, so all you need to do is keep track of how many layers you have, and their distances from each other.
In conclusion, the main selling point of the STAR framework is that it eliminates completely the notion of BRDF, using instead a phase function for scattering (for which a general-purpose analytical model exists, by the way: Mie scattering - though it's hell to compute, so approximations are required). This increases the array of materials that can be represented and generalizes volume rendering nicely. Of course, BRDF's can
still be used, but it defeats the point, as many BRDF's are actually already approximations to some form of scattering or are just glorified surface distributions.
I am confident I am not the first person to come up with this, and a lot of high-end rendering systems probably have already all of this implemented in one way or another - minus perhaps interference - but I look forward to implementing this for myself to see how it would work in practice. After all, this is all interesting new territory for me, and the point of all this is to have fun discovering new stuff, not necessarily produce the most efficient and comprehensive algorithm ever. It's pretty likely that in a few years, nobody except me will remember this article I wrote today, but that's all right.
In any case, I think I am nearing the state of the art in rendering at this point, so once I finish exploring this whole scattering thing, I'll probably move on to something different, perhaps game design, who knows (this is GameDev, after all). I will have spent over a year on ray-tracing and lighting theory, but I feel it has been worth it and I learned a lot of good physics and mathematics. I would definitely recommend to anyone interested in this to do the same.