Now we need to bring out LUT into a skin shader. For this tutorial, we’ll be using the Bust_Outdoors level from the Digital Human content pack, which you get through the Epic Games Launcher (via Unreal Engine -> Learn).
Once you’re there, we’ll move on to some quick theory:
When recolouring the skin, what we want is the ability to change just the underlying skin tone. In an ideal world, we also want to be able to texture the skin in the normal workflow way – so we texture an albedo map. This makes it easier to author, and will work with existing assets you may have.
But how do we do this? If we use a Hue/Saturation/Lightness adjustment to the skin, we may end up changing the colour of the lips or other scars and blemishes, too – which is not what we want. All we want to change is the chromophore contribution to the skin tone.
The solution is to divide the albedo texture by the original chromophore contribution, then multiply it by the new chromorphore contribution:
α= (α/ β)γ
Where α is the albedo, β is the underlying chromophore contribution, and γ is the new target chromophore contirbution.
By dividing, we remove the chromophore contribution from the albedo, leaving only the remaining color contribution from blemishes, lips, etc. We can then add in a new color by multiplying it in.
First, we need to get the chromophore contribution in the head texture. To do this,:
- Open the Albedo in Photoshop
- Select an area of skin that doesn’t have too many blemishes and is fairly even in skin tone
- Go Filter -> Blur -> Average
- Use the color picker to get the Hex value for this new skin color
Next we need to import our LUT correctly. Import the PNG we output from our Monte Carlo simulation, then double click the uasset, and change its settings to the following, then save:
These are required so we keep defined edges between our 3 LUT areas – using a different filter will cause blurry edges. Clamping the texture prevents large or negative values in the shader looping back around – it just makes it less prone to user-error.
Next, we shall head into UE4 and create a new Material Function called MF_SkinLUT. Open it up and construct the following:
What’s going on here?
We have 3 areas of our LUT for different melanin blends. We need to sample two of these areas and blend between them. For example, if we had a blend value of 0.25, we need to sample a pixel from the first LUT area (0.01 blend) and one from the second LUT area (0.5 blend), and then pick a value that is halfway between those sampled colors.
We will select which pixel we sample based on melanin fraction (our “x-axis” in each area, and hemoglobin fraction is our “y-axis”)
Now open up the M_Skin_Bust from the character in our scene, it contains the head skin material in this scene:
Now, drag in you MF_SkinLUT material function. Add in three scalar inputs, like so:
Apply the following settings to them:
Next, create a Vector Parameter and set the sRGB Hex value we extracted from Photoshop:
Now, divide the Albedo RGB node by this amount, then multiply that output by the output of your Material Function, just like this:
Now, create a Material Instance of this Material and apply it back to your head. We do this so we can change out skin chromophore values without having to recompile shaders. You should end up with the following:
Now we can start changing the skin tones!
As an extension task, you can completely remove the Material Function and just multiply in any colour you like for some fantasy-genre skin tones:
As you can see, we maintain pinkness in the lips (that is more evident in lighter tones)
If you’re using Unity, you can use the following Shader Graph setup:
The process is identical – clamp the LUT, nearest pixel filter.
Here it in on the Digital Human from The Heretic project which you can grab from the Asset Store in Unity: