The following OSL material emulates the skin shader made by Tony Reynolds which employs layered subsurface scattering modulated by red, green, and blue wavelengths. You can get the OSL code for the material here.
I'd love to get feedback from folks trying this material out. Feel free to post your comments here!
I'd also be interested to hear what folks like Vlado (who know tons more about physics than I do) think of the the shader's approach, which seems to me to address a lot of concerns that users encountered with other subsurface shader approaches.
Here's some info on the material:
Wavelength dependent subsurface scattering
A mean free path describes the distance a photon travels through a particular material before it gets scattered or absorbed. The mean free path is a wavelength dependent value. If we simplify our visible spectrum to three colors (red, green and blue), the mean free path will take a different value for each one of these colors.
Each wavelength of light penetrates the skin to a different depth. If we simplify our visible spectrum to three colors (red, green and blue) the mean free path (the distance a photon travels through a particular material before it gets scattered or absorbed) will take a different value for each one of these colors. For human skin red goes the deepest, then green, and blue is quite shallow.
Based on this, the shader separates the main color texture (the Subsurface Color) into its red, green and blue components, and pipes these into three subsurface shaders, which are then combined together using weighted averages (the standard behavior for OSL closures).
The depth of each these three subsurface shaders (i.e the mean free path) is then driven by the corresponding red, green, and blue channel of the "RGB Scatter Depth" color. In other words, the RGB Scatter Depth is not actually a color per se, but rather represents the scattering coefficients in the volume for the red, green and blue wavelengths. So setting the red channel of the Wavelength RGB Depth color to 1.0 means the depth of the red wavelength is at 100% while setting it to 0.7 means it is 70%, and so on for all three RGB channels.
One added benefit of this approach is that it virtually eliminates the "green error" that can appear on thin parts of an SSS2 material when the scattering amount it set to large values since it linearly blends multiple subsurface shaders together, rather than the more complex interaction of the subsurface and scatter colors in the SSS2 material, which, while more physically correct, can be unintuitive for artists to work with
Specular and single scatter reflections
Additionally, the shader has a Lambertian diffuse term to simulate single scattering, which can be thought of as a diffused reflection. This would therefore be grey since skin is a dielectric material.
The shader does not have any specular or reflection, and is intended to be combined with the reflection properties of a VrayMtl using an additive blendMtl. I like to use two GGX speculars with differing glossiness values to get the popular two-lobe specular for skin.
Art and science
While this approach emulates a physically accurate model of subsurface scattering, the shader is primarily designed to be artist friendly. One drawback of layered skin shaders like the VraySkinMtl is that a user needs to mix different, often unintuitive, colors together to arrive at the desired skin color. As autodesk says of their layered Misss* shader, "Each layer had it's distinct color, which made it difficult to aim for a given "final" color, and changing the balance between the layers threw the color off."
In contrast, with this shader the user simply inputs a single texture map of the skin into the Subsurface Color and that's what you get. Likewise, the user sets the color for the Wavelength RGB Depth that they want to see in the bleed (keeping in mind that this also affects the scatter depth) and you get that too.WYSIWYG.
One additional note: I optimistically included a subdiv parameter in theshader to make it forward compatible for when this is added into future code for the vray_subsurface osl closure.
I'd love to get feedback from folks trying this material out. Feel free to post your comments here!
I'd also be interested to hear what folks like Vlado (who know tons more about physics than I do) think of the the shader's approach, which seems to me to address a lot of concerns that users encountered with other subsurface shader approaches.
Here's some info on the material:
Wavelength dependent subsurface scattering
A mean free path describes the distance a photon travels through a particular material before it gets scattered or absorbed. The mean free path is a wavelength dependent value. If we simplify our visible spectrum to three colors (red, green and blue), the mean free path will take a different value for each one of these colors.
Each wavelength of light penetrates the skin to a different depth. If we simplify our visible spectrum to three colors (red, green and blue) the mean free path (the distance a photon travels through a particular material before it gets scattered or absorbed) will take a different value for each one of these colors. For human skin red goes the deepest, then green, and blue is quite shallow.
Based on this, the shader separates the main color texture (the Subsurface Color) into its red, green and blue components, and pipes these into three subsurface shaders, which are then combined together using weighted averages (the standard behavior for OSL closures).
The depth of each these three subsurface shaders (i.e the mean free path) is then driven by the corresponding red, green, and blue channel of the "RGB Scatter Depth" color. In other words, the RGB Scatter Depth is not actually a color per se, but rather represents the scattering coefficients in the volume for the red, green and blue wavelengths. So setting the red channel of the Wavelength RGB Depth color to 1.0 means the depth of the red wavelength is at 100% while setting it to 0.7 means it is 70%, and so on for all three RGB channels.
One added benefit of this approach is that it virtually eliminates the "green error" that can appear on thin parts of an SSS2 material when the scattering amount it set to large values since it linearly blends multiple subsurface shaders together, rather than the more complex interaction of the subsurface and scatter colors in the SSS2 material, which, while more physically correct, can be unintuitive for artists to work with
Specular and single scatter reflections
Additionally, the shader has a Lambertian diffuse term to simulate single scattering, which can be thought of as a diffused reflection. This would therefore be grey since skin is a dielectric material.
The shader does not have any specular or reflection, and is intended to be combined with the reflection properties of a VrayMtl using an additive blendMtl. I like to use two GGX speculars with differing glossiness values to get the popular two-lobe specular for skin.
Art and science
While this approach emulates a physically accurate model of subsurface scattering, the shader is primarily designed to be artist friendly. One drawback of layered skin shaders like the VraySkinMtl is that a user needs to mix different, often unintuitive, colors together to arrive at the desired skin color. As autodesk says of their layered Misss* shader, "Each layer had it's distinct color, which made it difficult to aim for a given "final" color, and changing the balance between the layers threw the color off."
In contrast, with this shader the user simply inputs a single texture map of the skin into the Subsurface Color and that's what you get. Likewise, the user sets the color for the Wavelength RGB Depth that they want to see in the bleed (keeping in mind that this also affects the scatter depth) and you get that too.WYSIWYG.
One additional note: I optimistically included a subdiv parameter in theshader to make it forward compatible for when this is added into future code for the vray_subsurface osl closure.
Comment