| On this page |
When light interacts with translucent objects, you can observe an effect known as subsurface scattering - or just SSS. With subsurface scattering, light can bounce around the medium multiple times, and sometimes gets absorbed and sometimes exits through the surface. The exit point of a light ray may not be the same as its entry point. In 3D computer graphics, subsurface scattering is crucial. Without this effect, translucent materials often have the appearance of clay or rubber.
To see subsurface scattering in reality, just hold your hand against a strong light source. You’ll see a glowing area around your fingers and maybe other structures like veins. The inner parts of the fingers appear darker because the tissue there is thicker and absorbs light. Other typical materials and objects with subsurface scattering are wax, plastic, milk, fruit juice, marble, leaves, or mushrooms, but also certain fabrics.
Transmissive materials are fundamentally different from SSS materials. In materials like glass or water, light passes through the medium unimpeded except for surface interactions. With SSS, however, the lights scatter and randomly change direction inside the medium (like a volume).
SSS in Karma ¶
Houdini’s Karma CPU and Karma XPU render engines are capable of rendering subsurface scattering, but you need an appropriate shader on your object. With MaterialX you have two possibilities: the MaterialX Standard Surface VOP and
MaterialX Open PBR Surface VOP nodes. If you want to render with Karma CPU, you’ll also have access to VEX-based shaders.
Tip
In Karma CPU, it’s possible to build your own custom shader that has an SSS component by using the MaterialX Subsurface BSDF VOP, instead of using standard surface and PBR “uber” shaders.
Random walk ¶
One term you come across very often in conjunction with SSS is random walk. This method traces random paths of rays through an object’s volume. The algorithm simulates how light is scattered inside the mesh rather than doing surface-based approximations. As a result, you’ll preserve fine surface details, and get a correct representation of thin objects with sharp curves.
The flip side of this method is that it’s a stochastic process ( Monte Carlo ) introducing a certain amount of noise. This means that you might need higher samples and quality settings in Karma.
Parameters ¶
Note that the parameter names of the MtlX Standard Surface and OpenPBR Surface shaders are slightly different, but have equal functionality.
Tip
We recommend using photographic references for adjusting the SSS parameters.
Subsurface ¶
This parameter blends between full diffuse reflection (0) and full subsurface scattering (1). Note that, if you're using a standard surface or OpenPBR shader, SSS won’t appear to have any effect if metalness or transmission is set to 100% since those components replace diffuse and SSS components.
The head on the left side has full diffuse reflection. The Subsurface values are 0, 0.5, and 1.
Color ¶
You can define a target output color for the subsurface scattering effect. For example, if you choose a green color, the material mainly absorbs the incoming light’s blue and red parts of the spectrum. The green parts pass through the object and create the color that is finally visible.
The heads in the following image have equal subsurface properties and only color changes.
Radius ¶
Radius multiplied by Scale represents the average distance a light ray can travel through the object before it’s scattered inside the object’s volume for each color channel. This is a material-specific value known as mean free path.
Since Radius controls how rays are scattered in the RGB spectrum, the values may also affect the material’s overall color. The final color effect, however, strongly depends on the adjusted Scale value, and the object’s size and thickness. With 0 (black), there won’t be any scattering. Small values mean that light is quickly scattered and you’ll get a more opaque appearance. Higher values create more translucency.
Radius multiplied by Scale is a physical parameter measured in scene units. In MaterialX you can define how far the light travels for each component of the RGB spectrum to get more complex scattering. You don’t have to enter numerical values, and you can use the associated color field. This color is called mean free path color. The dots contain the Radius colors that were used for the images.
Tip
It’s also possible to set Radius directly to its final value and leaving Scale at 1. The separation between Radius and Scale is just for your convenience.
Scale ¶
This is a global multiplier for all Radius values. An object’s size influences its appearance: With identical SSS properties, a small object is more transparent to light than a huge object.
Let’s assume your scene scale is 1 m and you have a marble block with a size of 0.1 m (= 10 cm) in each direction. With the shader’s default Scale value of 1 and a purely white Radius, an average light ray can travel 1 m before it’s scattered.
For a correct result, Scale should be in relation to the size of the marble block and consider its dimensions. In order for the rays to be scattered, Scale must be decreased, for example to 0.005. If all Radius values are 1, the rays will be scattered after 0.005 m (= 5 mm). As a global rule of thumb, however, you can say that higher Scale values create a softer and more translucent look.
We also want to take a look at an (exaggerated) example - again with a scene scale of 1 m. Imagine an object with a size of 2 m that needs to be downscaled to 17 cm. The factor for this translation is 17 cm / 200 cm = 0.085. Now we also assume that you've found a subsurface Scale of 0.35 for the original object. To get the compensated Scale value, multiply both values:
-
0.35 * 0.085 = 0.02975
The Scale values in the images are 0.01, 0.1, and 1.
Anisotropy ¶
If you have a back light and want the light shine through an object more strongly, you need to increase Anisotropy and use positive values. This effect is called forward scattering. With negative values, you can achieve backward scattering and the object appears less translucent. Anisotropy distributes energy in different directions.
Note
For the more tech-savvy users: Anisotropy is the parameter for the standard Henyey-Greenstein phase function .
A value of 0 describes isotropic scattering where light is scattered evenly. The limits are -1 and 1, but we don’t recommend using the minimum and maximum values. In most cases the values will range between -0.5 and 0.5. For illustrative purposes, the Anisotropy values for the objects below are -0.5, 0, and 0.5. There’s a strong area light behind the heads to provoke the effect.
Maps ¶
Instead of a fixed value that is valid for an entire object, you can also connect texture maps with variable values to any parameter of the shader’s Subsurface tab:
-
Pure black represents a value of 0
-
Pure white stands for a value of 1
Note that, if the resulting value is smaller than 1, you’ll again see diffuse reflection in those areas. In the image below, a grayscale map is connected to the shader’s Subsurface parameter. The fading tones of the grayscale maps create a halo behind the Houdini logo. If you change the shader’s Base color, the diffuse reflection is shining through the map’s non-white areas. You can also think of the grayscale map as a “mask” for the diffuse lobe.
AOVs and LPEs ¶
You can extract an object’s SSS lighting contribution through a Light Path Expression and write it to a separate AOV.
On the Karma Render Settings LOP Image Output ▸ AOVs (Render Vars) tab, you can find a separate SSS section. Expand it, and turn on BSDF Labelled 'sss'.
Examples ¶
The following materials and their parameters are suggestions, not the answer to everything. Especially with SSS, perception plays an important role. Orange juice is a good example because some people think of it as a bright yellow liquid, while others would create a saturated orange with a higher amount of red. With human skin it’s similar and there are as many opinions on this as there are skin tones. Position, color, and intensity of the scene’s lights will also influence the final result and you may have to fine-tune your materials to make them look realistic.
Wax ¶
Candle wax is certainly one of the most often described materials in conjunction with subsurface scattering. The final appearance of the wax depends on the type of wax itself. Beeswax and soy wax tend to have a dull appearance with a touch of velvet. Natural beeswax has impurities like pollen that create a warm yellow or light orange tone.
Paraffin wax, on the other hand, is made of crude oil, and has a shiny or glossy look. Stearin candles are a mixture of stearic acid and palmitic acid. This type of wax can have a milky appearance with a less glossy surface. Pure paraffin and stearin are white substances, but can be dyed with any color.
A candle’s material also affects the SSS properties because the various types of wax have different densities. The differences might appear subtle, but can have an impact on the shader’s Scale parameter. The densities are:
-
Beeswax approx. 0.96 kg/m^3
-
Stearin wax approx. 0.94 kg/m^3
-
Paraffin wax approx. 0.90 kg/m^3
The candle in this example has a radius of 0.04 m (= 4 cm) with a height of approximately 0.15 m (= 15 cm) and is made of stearin. An additional Area Light LOP with Type set to Sphere, and a Color Temperature of
2000 mimics the candle flame.
The following table contains the shader’s Subsurface parameter values with descriptions. Note that you might also want to change the values of the Specular tab to give the candle a less glossy look, for example with a specular Roughness of 0.25.
| Parameter | Value | Description |
|---|---|---|
| Subsurface |
1
|
A value of 1 means full subsurface scattering without diffuse reflection. The candle’s color is only determined by the Color and Radius parameters.
|
| Color |
0.5, 0, 0
|
This is the main color of the SSS effect and gives the candle its deep red tint. |
| Radius |
1, 0.3, 0.2
|
Here you specify how deep each component of the RGB spectrum can penetrate the object. The values create a subtle flesh tone in the more translucent parts near the top of the candle. |
| Scale |
0.02
|
This value will be multiplied with the three Radius values and is responsible for the material’s actual look. The candle’s dimensions also dictate the final Scale. With higher settings you can create a less dense appearance with more “glow”. |
| Anisotropy |
0.35
|
This value creates a slightly more realistic look, because wax tends to scatter forward. |
The image series below illustrates how the look changes if you keep the subsurface values, but make the candle bigger. The first image shows the original candle. The following three images use Global Scale transformation values of 0.5, 1, and 2.
Orange juice ¶
Orange juice is a complex suspension of water, sugars like glucose and fructose, organic acids such as citric acid, and other compounds. You can also find varying amounts of fruit pulp in orange juice. The fact there’s not that one type of orange juice gives you some freedom in terms of color and SSS values.
The glass has a height of 0.13 m (= 13 cm), and the upper edge uses a radius of 0.043 m (= 4.3 cm). Inside the glass, there’s a solid geometry that represents the juice. The juice itself also has slightly transparent characteristics and you can play with the shader’s Transmission parameters and colors. For Transmission, you can try a value around 0.1.
As before, here’s a table with the SSS values that were used for the image.
| Parameter | Value | Description |
|---|---|---|
| Subsurface |
1
|
Orange juice doesn’t show any diffuse reflection, so there’s only subsurface scattering. |
| Color |
1, 0.27, 0
|
This should be an orange or orange-yellow tone for obvious reasons. You can use the color field to choose an appropriate color. |
| Radius |
1, 0.9, 0
|
The red and blue radius values say that rays of this part of the spectrum travel longest. The blue parts, however, are completely absorbed. The values create a fresh yellow tone that is visible in the translucent areas of the fluid. |
| Scale |
0.013
|
Play with different values to create your own version of orange juice! |
| Anisotropy |
-0.5
|
This value darkens the inner parts of the fluid where light rays have to travel longer. Backward scattering was chosen to amplify the “halo” effect. With forward scattering (> 0), the fluid becomes brighter with a higher proportion of yellow.
|
Milk ¶
The milk example uses the same setup as the orange juice scene. In terms of shading you typically have to differentiate between whole milk and low-fat milk. Whole milk has a slightly yellow touch due to its higher fat content. This tint shouldn’t be too prominent and only visible in more translucent areas.
If you choose a high value for Scale, it often happens that the milk has a thin and watery look similar to starch dissolved in water. If the value is very small, the fluid might have a more creamy and heavy look. The left image has a Scale of 0.01, on right image the value is 0.0005.
Similar to wax, milk shows strong forward scattering. However, an Anisotropy of 0 is acceptable if this value creates the desired look. You should also consider working on the shader’s Specular tab. The table contains the values for whole milk shown in the render.
| Parameter | Value | Description |
|---|---|---|
| Subsurface |
1
|
Milk doesn’t show any diffuse reflection, so there’s only subsurface scattering. |
| Color |
1, 1, 0.88
|
This could be a slightly yellow tone to point out that it’s whole milk. |
| Radius |
0.9, 0.75, 0.5
|
This combination of values also create a yellow tint in the fluid’s transmissive areas. |
| Scale |
0.001
|
This value creates the typical “heavy” look of milk where rays are scattered directly below the surface. The fluid’s main body remains solid. |
| Anisotropy |
0.1
|
For a more realistic look, you can add a certain amount of forward scattering. |
Mushrooms ¶
Many mushrooms also show SSS properties as the ones in this example. The largest mushroom has a height of 0.1 m (= 10 cm) and serves as a reference for the shader’s Scale parameter. The mushrooms have a slightly translucent cap, but there’s also a certain amount of diffuse reflection. Therefore, the Subsurface parameter’s value should be smaller than 1. The Color and Radius settings strongly depend on the mushroom’s own coloring. In this scene, the predominant colors are shades of brown or dark orange.
In contrast to other scenes of this guide, the mushrooms are illuminated by a Spot Light LOP with a Color Temperature of
5500 Kelvin. From the camera’s perspective, the spotlight is located to the left of the object.
The choice of the object’s Scale parameter is certainly the most difficult part due to the low Subsurface value. With strong illumination, the thinner parts near the edges of the cap appear semi-translucent and often show a typical “halo”. A positive Anisotropy value can help to amplify this effect.
| Parameter | Value | Description |
|---|---|---|
| Subsurface |
0.45
|
This value allows for stronger diffuse reflection. |
| Color |
0.1, 0.05, 0
|
A dark brown color goes well with the color of the mushroom. |
| Radius |
0.15, 0.09, 0
|
The Radius color is a also a brown tone, but with a slightly higher proportion of yellow. Blue parts will be completely absorbed (0).
|
| Scale |
0.007
|
This value amplifies the translucent look on the cap’s edge. |
| Anisotropy |
0.1
|
For a more pronounced “halo”, you can add forward scattering. |
Skin ¶
Skin shaders can become very complex, especially if you want to consider different skin layers like the epidermis. The MaterialX surface shaders don’t support layers like shallow, medium, or deep you might know from other material systems.
Skin material would normally have a higher red Radius value since red light penetrates deepest into the skin compared to green and blue parts of the RGB spectrum. A possible combination of Radius values is 1, 0.15, 0.1.
You can also consider other features, for example blood circulation, hair, skin type (dry, oily, rough), skin irregularities, pores, or freckles. Large parts of the skin are also covered with thin hair and create an effect similar to peach fuzz. Depending on the thickness on the skin, the SSS properties can vary for different parts of the body. For example, if you look at the head, the skin on the cheeks is typically thicker than the skin on the forehead. A map will consider these differences.
Other lobes like diffuse and specular reflection also have huge impact on the final look.
Thin-walled SSS ¶
Thin-walled objects like leaves also show SSS characteristics. To render this kind of geometry, you need a certain mode. This mode uses a limited set of subsurface scattering parameters where Radius, Scale, and Anisotropy are not taken into account:
-
Set Subsurface to a value greater than
0 -
Choose a Color or connect a map
-
On the MtlX Standard Surface or MtlX OpenPBR shader, expand the Geometry section and turn on the Thin Walled mode
Tip
For thin-walled SSS, we recommend starting with a Subsurface value of 0.5. In standard surface and OpenPBR specs, thin-walled SSS is fully forward scattering. So with 1, the surface that receives light, won’t reflect any light back into the scene.
The image shows a thin surface without (left) and with (right) Thin Walled turned on. On the left you can see a blurred “shadow” of the sphere.
SSS trace sets ¶
If you split an object with an SSS material into different objects or subsets, you’ll see a discontinuity when you render the scene. To solve this problem, you can “combine” the objects with a trace set string attribute. Karma will then treat all subsets with the same trace set as one object.
To create a trace set, follow these steps:
-
Add a
Render Geometry Settings LOP to your network
-
Add the nodes you want to use with a trace set to the render setting’s Primitive parameters (wildcards like
/World/box/*are supported) -
On the Karma tab, expand the Shading section and turn on
SSS Traceset -
Enter a name for the trace set to the empty field, for example
sssbox -
Render the scene - SSS trace sets work with Karma CPU and Karma XPU
Here you can see a box without a trace set and the aforementioned discontinuity on the left. On the right you can see the same object with a trace set.