Realistic Skin Shader for XPS (Patreon)
Downloads
Content
UPDATE!!! Version : 2.0 (RealSkin PBR Preintegrated 2.fx) fixed some black artifacts
A skin shader built on the same pipeline production renderers
and AAA games use for skin: linear space lighting, curvature
driven pre-integrated subsurface scattering, GGX specular and
filmic tonemapping. Best used on characters with normal and specular maps.
This is NOT a tweak of the usual XPS skin shader. It is a
different approach from the ground up. Most homemade skin
shaders are artistic approximations: a global wrap term plus
hand tuned color tints. This one derives the look from the
geometry and from physical material constants.
It also fixes the seams that show up in almost every homemade
XPS skin shader. See section 5.
----------------------------------------------------------------
1. INSTALLATION
----------------------------------------------------------------
1) Copy this file:
RealSkin PBR Preintegrated 1.fx
into the "shaders" folder of your XPS install, normally:
...\XNALara_XPS\shaders\
2) Open XPS. If it was already running, close it and reopen it.
3) In the Control Window go to:
Shader > User written shader > RealSkin PBR Preintegrated 1
4) Done. The check mark means it is active.
5)
NOTE: XPS will generate a .fx.txt file next to the shader by
itself. That is the compilation listing. It is normal, leave it
alone.
----------------------------------------------------------------
2. IS THIS THE RIGHT SHADER FOR YOUR MODEL?
----------------------------------------------------------------
READ THIS FIRST. It will save you a lot of confusion.
USE IT FOR:
Models with photographic skin textures, a normal map and
ideally a specular map. Realistic characters, scans, ports
from modern games. This is where curvature driven scattering
and GGX specular actually have something to work with.
DO NOT USE IT FOR:
Toon and anime models. Their textures already have the
shading painted into them by the artist. A PBR skin shader
will not add realism to a flat toon texture, it will remove
the look that was baked in. For those models use a toon
shader instead.
The shader is doing its job correctly in both cases. It simply
has nothing to compute on a texture where the light was already
painted by hand.
----------------------------------------------------------------
3. THE 4 USER PARAMETERS
----------------------------------------------------------------
Set them in XPS under: Config > User parameters
All of them range from 0.0 to 1.0
..............................................................
PARAMETER 1 - SMOOTHNESS / WETNESS
..............................................................
0.0 = dry matte skin (roughness 0.60)
1.0 = wet skin (roughness 0.12)
Recommended: 0.25 - 0.45
In PBR this is ROUGHNESS, not "highlight size". It controls
how wide AND how intense the reflection is at the same time,
because in a real material those two things are not
independent. A rough surface scatters its reflection over a
wide area, which also makes it dimmer. That coupling is why
PBR materials read as real and ad hoc ones do not.
* Normal skin ......... 0.30
* Sweaty / oiled ...... 0.60
* Lips ................ 0.65
* Matte character ..... 0.10
..............................................................
PARAMETER 2 - SPECULAR REFLECTANCE
..............................................................
0.0 = physically correct skin F0 (0.028), x1
1.0 = x3, exaggerated photoshoot skin
Recommended: 0.25 - 0.5
At 0 this does NOT turn the highlight off. Real skin always
reflects around 2.8% of the light hitting it head on, and
pretending otherwise is exactly what makes CG skin look like
clay. If you want less shine, raise the roughness with
parameter 1 instead.
..............................................................
PARAMETER 3 - SUBSURFACE SCATTERING
..............................................................
0.0 = no scattering, plain Lambert diffuse
1.0 = maximum subsurface diffusion
Recommended: 0.5 - 0.8
This is the flagship parameter of the shader. It drives the
curvature based pre-integrated scattering described in
section 4. Nose, ears, lips, knuckles and fingers will light
up red on their own, while the forehead and chest stay clean.
You do not paint anything and you do not tune anything per
character.
..............................................................
PARAMETER 4 - SHADOW DARKNESS
..............................................................
0.0 = natural falloff
1.0 = deep, contrasted, near black shadows
Recommended: 0.4 - 0.7
Applies a power curve (exponent 1.7 to 5.0) to the shading
factor of all three lights. Since that factor runs from 0 to
1, raising it to a power above 1 sinks the shadow side and
leaves the lit side completely untouched: 1 to any power is
still 1. So it darkens and tightens the terminator without
dimming your character.
It is applied BEFORE each light's native "Shadow depth", so
that control still works if you want to lift the shadow back
up on one specific light.
It also acts on Light 3. That matters: Light 3 is half
Lambert fill, so it never drops below 0.5 at the equator and
was leaving a constant veil of light over the whole model
that no "Shadow depth" setting could remove.
..............................................................
RECOMMENDED STARTING POINT
..............................................................
Parameter 1 = 0.30
Parameter 2 = 0.35
Parameter 3 = 0.60
Parameter 4 = 0.55
HEADS UP: XPS initializes all 4 parameters to 0. If you just
enabled the shader and everything looks matte and flat, it is
NOT broken, the sliders are simply still at zero.
EXPOSURE is controlled with the light intensity sliders in
XPS, not with a shader parameter. The filmic tonemapping
means you can push those intensities well past 1.0 without
blowing the image out to flat white.
----------------------------------------------------------------
4. WHAT MAKES THIS DIFFERENT
----------------------------------------------------------------
* LINEAR SPACE LIGHTING
The diffuse texture and the light colors are converted from
sRGB to linear, ALL the light is accumulated in linear, and
the result is converted back at the very end. This is the
single biggest factor in how the result reads, and almost no
XPS shader does it. Adding lights in sRGB, which is the
normal thing to do, distorts the terminator, dirties the
blend between two differently colored lights and flattens
every gradient.
* CURVATURE DRIVEN PRE-INTEGRATED SCATTERING (Penner)
Instead of one global wrap term applied equally to the whole
body, the shader measures the actual CURVATURE of the mesh at
every pixel using screen space derivatives, and scatters the
light more where the geometry curves more. It also scatters
PER CHANNEL: red travels several times further under the skin
than green and blue, which is why skin shadows go red.
The result comes out of the geometry itself. Thin, curved
parts glow, flat parts do not, automatically.
* GGX SPECULAR INSTEAD OF BLINN-PHONG
GGX has the long tail that skin actually has: the highlight
does not end abruptly, it fades. With Schlick Fresnel over
the physical F0 of skin (0.028) and Smith visibility.
* ENERGY CONSERVATION
Light reflected by the specular layer cannot come back out as
diffuse, so it is subtracted. Without this, shiny skin ends
up looking lit from the inside.
* FILMIC TONEMAPPING (ACES)
Most shaders end in saturate(), which CLIPS at 1.0: strong
highlights become flat white blobs with no gradient. Here a
filmic curve rolls the highlights off smoothly the way a real
camera does. This is a large part of what makes a render look
rendered.
The scene is pre-exposed by 0.6 before the curve, because the
Narkowicz ACES fit expects a scene already exposed with mid
grey near 0.18, while XPS hands over values with mid grey
near 0.5. Without that pre-exposure the curve works in its
upper range and returns MORE light than it receives, which
washes the image out.
* PORE MICRO-OCCLUSION
Derives cavity from the difference between the detail normal
and the geometric normal, and darkens slightly there. Real
depth in pores and wrinkles with no AO map required.
----------------------------------------------------------------
5. SEAMS, AND WHY THIS SHADER HAS NONE
----------------------------------------------------------------
If you have tried homemade skin shaders for XPS you have
probably seen a strange line running down the center of the
face, or a hard cut at the neck. There are four common causes.
All four are fixed here. Documented in case you write your own
shaders:
1) NORMAL MAP DECODING
XPS models have MIRRORED UVs down the center of the face and
the body. Tangent handedness flips at the mirror line. If
the normal map is reconstructed incorrectly - ignoring the Z
channel, using a skewed bias, or failing to invert the green
channel as the XPS convention requires - the lighting splits
right there. You must decode all THREE channels and apply
the TangentSpace_R/G/B remap with green negated.
2) VFACE
When a back face is detected, flip ONLY the normal. If you
also flip the tangent and the bitangent you create a hard
discontinuity at the boundary between front and back faces.
3) CullMode = NONE
People add this "to avoid seams" and get the exact opposite:
it draws back faces and shades them inverted. Do not set it.
Let XPS control that render state from its own options.
4) RENDER GROUPS
If you sample the bump or specular texture on a mesh that
does not have one, another mesh's texture stays bound. The
result is a perfectly visible line exactly at the border
between two meshes: face/neck, neck/torso. You have to check
render group tables before sampling.
The subtle part almost nobody catches: the specular MATH is
safe to run on every mesh. The only thing that has to be
filtered by render group is TEXTURE SAMPLING.
----------------------------------------------------------------
6. LIGHTING TIPS
----------------------------------------------------------------
* Use all 3 lights. The shader treats Light 3 as soft hemisphere
fill with no specular contribution, specifically for that job.
* Put Light 2 BEHIND the model at low intensity and raise
parameter 3. That backlight triggers the transmission term
and lights up ears, nostrils and fingers in red. It is the
single most convincing effect in the whole shader.
* Enable bump maps in XPS Options, or you lose the pore
micro-occlusion entirely.
* Push light intensity above 1.0 freely. The filmic curve will
compress the highlights instead of clipping them. That is how
you expose, since there is no exposure parameter.
* High parameter 4 (0.6+) with a single strong key light gives
an excellent dramatic portrait look.
* If the character has a specular map, its alpha channel drives
roughness and overrides parameter 1 on that mesh. That is
intentional: the model's own map knows better than a global
slider where the skin is shinier.
----------------------------------------------------------------
7. TROUBLESHOOTING
----------------------------------------------------------------
"Everything looks flat and matte when I enable it"
All 4 parameters are at 0, which is how XPS initializes
them. Go to Config > User parameters and enter the
recommended values from section 3.
"It looks worse than the default shader on my model"
Check section 2. If it is a toon or anime model with flat
painted textures, this shader is the wrong tool. Use a toon
shader for those.
"Parameter 1 does nothing on some meshes"
That mesh has a specular map with glossiness in the alpha
channel, and the map takes priority. Intentional.
"The image is too bright / washed out"
Lower the light intensities in XPS and raise parameter 4.
"Too dark"
Raise the light intensities. You can go well above 1.0
safely thanks to the tonemapping.
"The subsurface effect is too strong or almost invisible
everywhere"
Curvature is measured in screen space, so it depends on the
scale of your model. Open the .fx in a text editor and look
for this line:
float curvature = saturate(deltaN / max(deltaP, 0.00001) * 1.5);
Raise or lower that 1.5 to taste. Also note the effect is
naturally stronger in close ups than in wide shots. That is
inherent to screen space curvature, not a bug.
"I still see a seam"
It is almost certainly the MODEL, not the shader. Models
imported from .obj inherit render groups incorrectly in
XPS. Convert the model to .xps / .mesh format and retry.
"Hair or eyelashes look wrong"
This is a SKIN shader. Transparent hair and eyes live in
render groups without shading and the shader passes them
through untouched, but if your model has its hair assigned
to a skin render group it will be shaded as skin.
"XPS throws a compile error"
Make sure you copied the complete .fx and that your XPS
version supports user shaders (11.8.x or newer).
----------------------------------------------------------------
8. CREDITS AND LICENSE
----------------------------------------------------------------
Built on XNAaraL's XNALara / XPS shader structure.
The render group tables, the correct TBN construction and the
normal map channel conventions come from dasliebesverbot's (MF)
"Enhanced Shading" shader on DeviantArt, which is the best
public reference in existence on how XPS user shaders actually
work. Full credit to them:
https://www.deviantart.com/dasliebesverbot/journal/
Enhanced-Shading-Custom-shader-957472601
The pre-integrated skin technique is based on Eric Penner's
"Pre-Integrated Skin Shading". The ACES tonemapping curve is
Krzysztof Narkowicz's analytic fit.
LICENSE
Free software, same as the shader it inherits from. You may
use, modify and redistribute it freely. The ONLY condition:
if you modify it, share your modifications freely too.
Free for personal and commercial renders. Credit is always
appreciated but not required.
If you make something nice with it, show me. That is why I am
sharing it.