Fake SSS

This is a shader which fakes the sub surface scattering effect in RenderMan efficiently.

Here is the algorithm for the shader:

  1. Before anything else, backup the point and normal attributes of the surface, and set the opacity
  2. Setup the reflections that will give the glass look on the top layer. In this case a HDR environment map
  3. Setup the lighting calculations for the top layer
  4. Setup displacement for the sub layer with a displacement map
  5. Setup the light calculations for the sub layer using the displaced point and normal attributes
  6. Before the renderer outputs anything, restore the original point and normal attributes so the surface looks smooth, and combine the light and color calculation results

I used a HDR map for lighting and a 4k image I generated procedurally in After Effects using CC Ball and Gaussian Blur plugins for a displacement map. To the right is a sample of the displacement map.

Here are the settings I used with the shader:

"float tsrough" .75
"float Kd" 0.4
"float Ks" .3
"float Ka" .1
"float Ktop" .1
"float Kenv" .6
"color hicolor" [0.137 0.262 1.0]
"string envname" ["../textures/Dock-SkyDome.tex"]
"string envspace" ["world"]
"float ssrough" .3
"float subKa" .5
"float subKd" 3
"float subKs" .4
"color subCs" [1 1 1]
"float Km" 40
"float Ksub" .4
"color locolor" [.2 0 .8]
"string dispmap" ["../textures/Comp.tex"]
"color sp1" [0.4 0.1 0.8] 
"color sp2" [0.5 0.2 0.8] 
"color sp3" [0.6 0.1 0.7] 
"color sp4" [0.7 0.2 0.4] 
"color sp5" [0.7 0.1 0.2] 
"color sp6" [0.7 0.2 0.1] 
"color sp7" [0.8 0.1 0.1] 
#"float ssRmodcont" .3 #enable line 78 in FSSEshader.sl to use 
#"float ssGmodcont" .2 #enable line 79 in FSSEshader.sl to use 
#"float ssBmodcont" .6 #enable line 80 in FSSEshader.sl to use 
"float subSb" 1 
#"float sfreq" 100 #enable lines 69, 70 and disable line 71 to use 
#"float tfreq" 150 #enable lines 69, 70 and disable line 71 to use

ssXmodcont was a variable I added later to the shader just to experiment with. What it does is to pick up the defined color channel from the color variables array and apply a mod function on it which was supposed to cut down the intensity of a channel effectively. For instance red cannot be ligher than 0.5 out of 1 if ssRmodcont value is 0.5. This function is very unstable and should be handled carefully.

sfreq and tfreq were the variables I used to test the displacement calculations with basic noise before I went ahead and created a monster displacement map.

Km controls the displacement amount, and the reason it is so high is because the displacement map is a little blurry and smooth, the reflection hilites don’t really show up with small values of displacement. This way the object goes out of boundaries a lot and creates this noise and sharp colors.

Here are links for the shader and the render file: