Page MenuHome

Cycles: add anisotropy to random walk subsurface scattering.
Changes PlannedPublic

Authored by Brecht Van Lommel (brecht) on Mar 3 2018, 2:06 AM.


Group Reviewers

The tricky part is the surface color and anisotropy to albedo mapping. We simulate scattering for various different albedos and anisotropies, and then do a 2D function fit to invert that.

See section 6 of Path Traced Subsurface Scattering using Anisotropic Phase Functions and Non-Exponential Free Flights.

They do a two step function fit, but I couldn't get that working. For each anisotropy I got randomly different parameters that each fit the data pretty well, but if you try to fit a function to the parameters across all anisotropies it's much too noisy to fit anything useful.

So I fit the entire 2D function in one go, which may not have the best accuracy. It seems to work except for very high anisotropy, I need to look at that more closely. If anyone thinks it's fun to find a better fit feel free to try, the program to generate the data and do the fit is in the patch.

I haven't tried testing performance or cleaning/optimizing the code yet.

Diff Detail

rB Blender
Build Status
Buildable 1282
Build 1282: arc lint + arc unit

Event Timeline

Brecht Van Lommel (brecht) edited the summary of this revision. (Show Details)

Current results:

Albedo mapping in master
Albedo mapping with anisotropy

Wouldn't mind having a look into fit, but crazy times here.. Will see what i can do!


Always add file header. Having explanation what it does and how to use also helps a lot.


Why's that float3 which uses double?


Where this magic is coming from?

"subsurface random walk" and "subsurface base color mix" tests are broken with this patch. Is it something expected (mapping changes etc) or is it something to be avoid/solved?

Thanks for the review, I imagine you have more important stuff to work on than helping with this function fit.

There are some differences with the previous albedo mapping, which can also be seen in the anisotropy 0.0 column in the table above. The new mapping actually seems a bit more accurate than the previous one for the isotropic case.

Playing around with the anisotropy parameter, I'm not sure it's actually all that useful? The results are often similar to just changing the radius, with more forward scattering acting like a larger radius by going deeper into the volume. The diffuse boundaries probably kill a lot of the differences. It's also quite difficult to tell the difference between the images in the Pixar paper. Here's a test where I roughly modified the radius to get a closer result for the chosen anisotropy (I could probably get them closer).


The annoying thing is that with higher anisotropy it renders slower and more noisy (due to needing more bounces). And so users might tweak the anisotropy as if it was a subsurface scale, without realizing that they are getting a slower/noisier render for no good reason. So in some ways adding this control could be harmful, not sure what the right solution would be.

I would imagine that anisotropy could be more useful than radius in following cases:

  • Animation
  • Objects with some high-frequency details, with regions of lower details regions. Anisotropy might prevent some blurness from lower details regions to higher details ones. How much visible is that -- can't really tell. Might very well be similar to reducing radius indeed.

It's also quite difficult to tell the difference between the images in the Pixar paper.

I don't know if this is useful to you or not, but I searched google for anisotropy examples and found the most interesting piece on the solidangle support site. There is a section on anisotropy with a little explanation of how the algorithm works and 3 pictures with a very big difference.

@Sergey Sharybin (sergey), I'm not sure what you mean by animation? We are missing a Subsurface Scale in the principled BSDF to make the radius easier to tweak (or animate), similar to what we have in the Subsurface Scattering node.

@John (Jns_76), we know just changing the anisotropy makes a big difference, that can be seen in the crab renders above. But my observation was that you can get something quite similar by just changing the albedo and radius,

Here's the images from the Pixar paper for easy comparison.

Anisotropy 0.0Anisotropy 0.8

They don't to mention if they tweaked the radius to get matching results, but they must have. It could have been done manually, or with some automatic mapping similar to the albedo.

@Brecht Van Lommel (brecht), was talking about character animation, with deformations and such.

Brecht Van Lommel (brecht) marked 3 inline comments as done.

Address comments, clamp anisotropy to 0.98 for which the fit is decent.

Brecht Van Lommel (brecht) planned changes to this revision.Jul 26 2019, 3:21 PM

I bumped into these after perhaps finding an issue with the Subsurface scattering radius. Values of 0 results in color tone of that RGB channel.

After reading a bit through this post. Anisotropic Scattering is actually super useful. I use a different Physical Engine called Thea Render and we have the option to use Henyey-Greenstein for Phase Function. (
With the use of the Assemetry we can than control the scattering effect happening deeper inside the object or more to the surface. This mimics materials like marble and stone also called back-scattering, they use negative numbers. Things like flesh, organic use positive numbers, called forward-scattering