RealSkinShader Tutorial

TUTORIAL : How to achieve more realistic skin textures in Poser 5 (and above)

Introduction

The renders on the left use the standard DAZ Hi-Resolution texture maps. The renders on the right are with the same maps, together with the techniques described in this tutorial.

Full Render

Close-up

* Renders are from Poser version 5, production quality using FireFly, shadows on, min shading rate 0.2, Maximum texture resolution 4096, 2 infinite white lights..

The techniques below are a modified application of the method described at http://www.optidigit.com/stevens/shadetut.html, so thank you to Steven Stahlberg for all his work in this area. The main difference between Steven’s method and the method below is that I am using a dot product between the polygon and the main light to “redden” the texture colour for faking Sub-Surface Scattering (sss) instead of using a ramp. I found the ramp method required too much fine tuning to get the right effect under different lighting conditions. The method below also simplifies the specular nodes.

How To Do It!

The method described below has been implemented on the PC and Mac versions of Poser 5 and 6. I’m sure it could not be implemented on Poser version 4 (or below). Given the complexity of setting up the nodes, I have developed a script to assist, which is available from my Renderosity marketplace. This script is not essential for implementing this system (although good maths and patience is!).

The following node system has to be set-up for each skin texture. If you are using the Victoria 3 model (or similar), you will need to set it up for each individual head and body material. Once you have it setup for one body material, I recommend saving that node setup as a material and applying it to all the other body materials.

In the material room, the entire node set-up for one of the body materials (for Victoria 3 in this case) looks like this…..

Although this looks complicated, we will go through each section in detail so you know what the purpose of the nodes are, and how to set them up.

1) Diffuse Colour

The diffuse colour is based on a texture map (in this case the Hi-Res V3 texture), however 2 levels of spots are added to it (see Texture and Spots in the image below), along with a fresnel effect (Fresnel) and a fake sss effect (Incidence Ramp).

Note that the Incidence Ramp is pluged into both the Diffuse (through the Texture and Pots) and the Ambient. For the moment we will focus on the Diffuse and ignore the Ambient component.

Fresnel Effect

We’ll start with the easy part. A fresnel effect is a way of adding addition spots to the texture where the polygons are facing approximately 45 degrees to the camera. It is only a very slight effect, but you notice when it is not there!

The nodes for the Fresnel Effect look like this….

Combined_Fresnel is a maths_functions node. The Fresnel_Spots node is a spots node, and the Spot_Color is Red 114, Green 114, Blue 114. You can increase or decrease the fresnel effect by adjusting the Spot_Color color accordingly.

Incidence Ramp

OK, this is WAY the most complex part. If you make it though this section, the rest will be a breeze. If you are going to implement the Incident Ramp in your node setup – I really suggest getting my python script to do it for you.

The Incident Ramp fakes a sub-surface scattering (sss) effect – probably the most important part of the node setup. Sss is where light enters the skin, and either pops out the other side, or is bounced back a centimeter or two from where it entered. The Incidence Ramp fakes this effect by assuming that as skin becomes parallel to the main light, there will be more light passing through the skin, and that light will be tinted a red colour. So as the skin polygons of the model become parallel to the main light, tint the diffuse texture red. Mathmatically, there is done by taking the dot product of the vector from the main light and the vector of the normal of the polygon. That’s the theory – the node setup is as follows.

So bottom right is the normal vector of the polygon (Normal - which is a Variables->N node). The X, Y and Z components (X_Component, Y_Component and Z_Component - which are Math->component nodes) are multipled by the normalized vector from the main light (0.742592, 0.513875, -0.429522). To work this vector out, take your main light, convert it to a spotlight (if it’s not one already), take the X, Y and Z coords (xTran, yTran and zTran from the Transform section of the light info in Poser) of the light and sum the square of coordinates. Then take the square root of this sum (which is called the Vector Length in mathematical terms….) and divide the original light coordinates by this number. This gives you the Normalised vector for the main light – which you enter into Value_2 of X_Multiplied, Y_Multiplied and Z_Multipled (which are Math->math_functions nodes) in the node setup above.

Are you still with me?????

A working example. My main light coordinates are (31.687, 21.978, -18.33)….

Vector Length = squareroot (xTran*xTran + yTran*yTran + zTran*zTran)
= squareroot (31.687*31.689 + 21.978 * 21.978 + 18.33*18.33)
= 42.6976

Normalize main light vector = xTran/Vector Length, yTran/Vector Length, zTran/Vector Length
= 31.687 / 42.6976, 21.978 / 42.6976, -18.33 / 42.6976
= 0.742592, 0.513875, -0.429522 (plus or minus some rounding - which are the numbers used in the node above)

The remaining nodes in the screen-shot above are all Math->math_functions nodes, and add the vector components together, take the absolute value, and subtract from 1, to get a value 0 to 1, representing the degree the polygon is facing the main light. Polygon's facing the main light will have a value of 0, and those parallel will have a value of 1.

OK, all that sounds pretty complex, but it is very simple once you’ve done it a couple of times. In the end, I wrote the python script because everytime I moved my main light I would have to re-do the mathes and enter the new figures into the nodes for each material.

Is it worth it? Well….yes. I tried about 5 or 6 other ways to fake sss. But this method was definitely the best. There are certainly other ways – try them – try this method. You decide.

Texture and Spots

This is where it is all put together. The node setup looks like this.

Try not to get confused with the changing layout here – I’ve move nodes around to clearly show the setup. Bottom left are 2 sets of spots. Spots_1 are small red spots (Base_Color = black, Spot_Color = Red 4, Green 10, Blue 10). Spots_2 are larger spots (Base_Color = black, Spot_Color = Red 114, Green 107, Blue 94). Play around with the Spot_Size,Threashold and colors to get the effect you want. Note that the spot colors are the colors that are SUBTRACTED from the texture – not added.

The spots are added together in a color_math node (Combine_Spots) and then added to the texture map in another color_math node (Combined_Spots_And_Texture). The combination then has the incidence ramp added to it in a color_maths node (Apply_Ramp) The Value_2 of Apply_Ramp controls the colour and power of the Incidence Ramp – which in this case I have set to Red 40, Green 15 Blue 0. Then there is one more color_math node (Subtract_Fresnel) which takes the output from Apply_Ramp, and subtracts the Fresnel spots from it. This result is then plugged into the Diffuse_Colour node of the material.

A word on texture maps…..I believe this technique works best on plain texture maps (such as the standard DAZ V3 Hi-Res maps). If you use the so-called “photoreal” texture maps you want need to use less fresnel and fewer spots. Because you are using less fresnel, you will end up with a little less “depth” to the image. Some of the “photoreal” texture maps also try and fake their own sss (not taking into account the scene lighting), so you will need to adjust the node set-up accordingly.

2) Ambient Colour

Setting the ambient colour is easy – simply plug the Incidence_Ramp we constructed for Diffuse into the Ambient.

The Ambient_Color controls the color and power of the effect. In this case it is set to Red 30 Green 0 Blue 0.

Why is the Incidence_Ramp connected to both diffuse and ambient? Well, it’s just what seems to work best. Oh, and I don’t recommend adding any blue into ambient. It creates a very cold feeling.

3) Specular, Bump and Displacement

These 3 components are related, so will be treated together.

Displacement

If you want the model to look a tad older, or a little plumper, add a Granite node into the displacement plug as above. 0.01 seems to be good displacement amount, although if you are going for the very lumpy look, try 0.02. Also adjust the Granite scale, shades and balance to get the effect you want.

Bump

No adjustments needed here. Although for models which does have a bump map, you can plug in a noise node.

Specular

Firstly, set Specular_Color to black, and Specular_Value to 0. You can try either a Blinn or Phong in the Alternate Specular. I personally find the Blinn has a little more adjustment and gets the look I want. You can get some interesting “wet:” looks by adjusting the Blinn or Phong parameters. Most importantly, set the Alternate_Specular color to a light shade of blue (Red 200, Green 220, Blue 255 in this case).

Now plug the bump map into the Specular_Color of your Blinn or Phong. This is essential for close-ups.

Python Script

If you want to automate this whole process, you can use the Real Skin Shader python script from my Renderosity marketplace.

You select the figure to set the materials for in the top left box, then select the main scene light in the top right. Then there are various parameters which you can tweak, and finally you hit Generate Nodes and it sets up the node system for each of the head and body materials.