No
No
No
I will give an overview of how subsurface scattering (or SSS for short) is implemented
in Unity’s High Definition Render Pipeline.
Due to time constraints, I will be brief. You can check the slides for more details later.
Let’s start by trying to understand what is subsurface scattering.
By definition, it is light transport within the participating media under the surface.
You also get some color bleeding around areas where illumination changes abruptly.
It appears that there’s a certain misconception that with SSS you get pronounced
color bleeding near all shadow boundaries. In fact, it is very subtle if the shadow is
soft.
How is subsurface scattering typically implemented?
The first real-time SSS approach was proposed by Eugene d’Eon, and used a mixture
of Gaussians (4, to be specific) to create a numerical fit for a measured diffusion
profile.
This approach yields fantastic results, but it is still too expensive for games, even
today. Therefore, real-time constraints force us to implement SSS in the screen
space.
The filter is usually composed of 1 or 2 Gaussians and a Dirac delta function which, in
practice, means that you interpolate between the original and the blurred image.
A single Gaussian does a pretty good job at approximating multiple scattering.
However, even a mix of 2 Gaussians struggles to accurately represent the
combination of single and multiple scattering.
On the image, you can see the reference results in white, and the dual Gaussian
approximation in red.
After implementing the Gaussian mix model, we have encountered another problem -
it is not artist-friendly.
It is worth noting that a skilled artist can still achieve great results with the Gaussian
mix model. However, this can be a lengthy and complicated process, which is not a
right fit for Unity.
So, is there a better solution? Well, it is in the title of this talk. :-)
We implemented Burley’s normalized diffusion model, which we call the Disney SSS.
It provides an accurate fit for the reference data obtained using Monte Carlo
simulation.
Naturally, that means accounting for both single and multiple scattering.
It has only two parameters: the volume albedo A, and the shape parameter s. Both of
them can be interpreted as colors.
The shape parameter is inversely proportional to the scattering distance, and this is
what we expose in the UI.
If we look at the graph of the resulting profiles, two things become obvious:
1. The sharp peak and the long tail cannot be modeled with a single Gaussian
2. The resulting filter is clearly non-separable
The diffusion profile is normalized, and can be directly used as a probability density
function (or PDF for short). This is a useful property for Monte Carlo integration, as
we’ll see in a bit.
● The diffusion
profile is
normalized, it can
A diffuse BRDF approximates SSS when the scattering distance is within the footprint
of the pixel.
What this means is that both shading models should have the same visuals past a
certain distance.
In order to achieve that, we use the formulation of the Disney Diffuse BRDF to define
the diffuse transmission behavior at the dielectric boundary.
While it doesn’t match transmission defined by the GGX model, it’s still better than
assuming a Lambertian distribution.
We do not model specular transmission, and our model does not generalize to low-
albedo materials like glass.
You may notice that the post-scatter option does a better job at preserving detail, as
expected.
The difference is subtle, so I encourage you to look at the slides on a good display
later.
And for comparison, this is pre- and post-scatter.
You may notice that the post-scatter option does a better job at preserving detail, as
expected.
The difference is subtle, so I encourage you to look at the slides on a good display
later.
Since Burley’s diffusion profiles are normalized, SSS can be implemented as an
energy-conserving blur filter.
You can imagine light energy being redistributed from the point of entry across the
surrounding surface...
Lighting pass:
Compute incident radiance at the entry point of the surface
Perform diffuse transmission from the light direction into the surface
Apply the entry point albedo depending on the texturing mode
Record transmitted radiance in a render target
SSS pass:
Perform bilateral filtering of the radiance buffer with the diffusion profile around the
exit point
Apply the exit point albedo depending on the texturing mode
Perform diffuse transmission outside of the surface in the view direction
Ideally, we should directly sample the surface of the object*, but that is too expensive
for real-time applications.
Instead, we use a set of samples which we precompute offline, and (conceptually)
place them on a disk, pictured here with a dashed green line.
As the picture demonstrates, this planar approximation is not necessarily a good
match for the shape of the surface.
What’s arguably worse, since projection of samples from the disk onto the surface
distorts distances, projected samples end up within a different distribution. We’ll have
to do something about that, but first…
Note: Halley’s method is the second algorithm in the class of Householder's methods,
after Newton's method.
Finally, we use the Fibonacci sequence to uniformly sample the polar angle. It yields
a good sample distribution on spheres and disks, and is useful in many contexts,
such as reflection probe filtering.
We use the Monte Carlo integration method to perform convolution across the disk. It
simply boils down to the dot product of sample values and weights.
The importance sampling process results in a precomputed sample pattern which can
look like this.
Notice that we sample more densely near the origin since most of the energy is
concentrated there.
Now that we know how to precompute the samples, let’s return to our planar
approximation...
Since the surface geometry is not aligned to the disk, and we use precomputed
samples, our only option is to re-weight the samples somehow. This process is called
bilateral filtering.
Bilateral filtering makes convolution take depth into account.
Getting this right is very important, not just for a quality boost, but also to avoid the
background bleeding onto the foreground, and vice versa.
Using the Monte Carlo formulation of convolution, sample weights are defined as the
ratio between the value of the function and the PDF.
Modifying the value of the function is easy - we just evaluate the profile using the
actual Euclidean distance between the entry and the exit points.
Note: for the ease of exposition, the math assumes a right triangle and thus uses the
Pythagorean theorem. Generally speaking, you should account for the perspective
distortion as well [Mikkelsen 2010].
Unfortunately, we cannot do the same for the PDF, since our sample positions are
already distributed according to this old “planar” PDF.
If we make a connection between the formula for Monte Carlo integration and the
quadrature formula for integration over area, we can see that the PDF value is
inversely proportional to the area associated with each sample.
But how do you compute this area? It’s possible to make certain assumptions about
the surface and add some cosine factors to account for slopes...
However, solving this problem in a general and robust way is hard, especially due to
the limited information in the screen space.
Instead, we can simply utilize the fact that our filter is meant to be energy conserving,
and normalize the weights to sum up to 1.
Now that we know how to perform bilateral filtering across the disk, let’s consider how
to place and orient this disk.
The disk is naturally placed at the intersection of the camera ray with the geometry, in
the world or the camera space.
But what about the orientation of the disk? We have several options.
The 0 order approximation is to align the disk parallel to the screen plane, which
directly corresponds to a disk in the screen space.
It’s simple and fast, but can result in poor sample distribution for geometry at oblique
angles.
A better solution is to align the disk with the tangent plane of the neighbourhood of the
surface point (1st order approximation).
This can be challenging because the G-Buffer typically does not contain the
interpolated vertex normal.
And, unfortunately, using the shading normal can result in artifacts, as it often has
little in common with the geometry around the surface point, and can even be back-
facing.
It’s worth noting that even the naive method performs quite well in practice.
SSS is also responsible for the translucent look of back-lit objects.
While the underlying physical process is exactly the same, for efficiency reasons, we
handle this effect in a more simple way.
Initially, we attempted to compute thickness at runtime solely using the distance to the
closest occluder given by the shadow map.
It quickly became apparent that this approach does not work well for fine geometric
features due to the limited precision of shadow maps.
With the setup you see on the screen, the compute shader which performs
convolution and merges diffuse and specular lighting buffers takes 1.16 milliseconds
to execute.
We also implemented the latest Gaussian mix model of Jorge Jimenez for
comparison.
If you can see the difference, you don’t need glasses. :-)
With a single parameter, the Disney model is very easy to control, and it’s possible to
achieve good results in a matter of minutes.
We also implemented the latest Gaussian mix model of Jorge Jimenez for
comparison.
If you can see the difference, you don’t need glasses. :-)
With a single parameter, the Disney model is very easy to control, and it’s possible to
achieve good results in a matter of minutes.
The primary advantage of the Disney model is sharper visuals, which preserve more
normal mapping details given the same scattering distance.
Many thanks to my colleague Sebastien Lachambre for allowing us to use the scan of
his head.
The primary advantage of the Disney model is sharper visuals, which preserve more
normal mapping details given the same scattering distance.
Many thanks to my colleague Sebastien Lachambre for allowing us to use the scan of
his head.
A few words about limitations...
Finally, thick object translucency makes too many assumptions to produce accurate
results for complex thick objects.
In the future, we would like to extend our implementation to properly support tangent-
space integration.
Since interpolated vertex normals are not available in the G-Buffer, our plan is to
compute a robust tangent space normal from the depth buffer.