Somewhere around the end of last year I was working on a small private project to see how realistic and "next-gen" I could go with rendering a human being and of course also to push the engine to it's limits ;)
Now I've finally come around to publishing an article here on my blog on my findings, ideas and gained knowledge about the subject.
First of all a big applause and praise to Jorge Jimenez who has spent quite some time on this topic and has made his work publicly available (http://www.iryoku.com/stare-into-the-future), which has inspired and helped me a lot in my own work and was the basis for most of it.
So the SSS (SubSurface-Scattering) technique that I'm using here is the one proposed by Jimenez in his 2011 paper. If you want to know how it works in detail you can check it out on his blog. Basically it's a screen-space blur that is run as a post-effect in the pixel shader using a seperable blur kernel for more efficient execution.
Key here is to blur the diffuse only part of the image (marked by the stencil buffer) to smooth out high frequency normal map (or bump) Information and to apply a color tint that makes the Skin appear more realistic in the sense that it simulates subsurface scattering (duh!) that happens under the Skin (light penetrating the Skin, scattering around and reflecting out again).
This technique is quite common nowadays and performs fairly well.
For the specular part I'm using two-lobes of the GGX distribution added on top of each other using a Ratio of 70% for the regular more smooth part of the Highlight and 30% for a more high frequent highlight that makes the details of the skin pores come out stronger.
This is a very subtle visible effect but it does help to pronounce the detail a bit more.
Another (very) important part of skin rendering is (yet again) indirect lighting.
The biggest issue when using extremely high resolution normal maps is that subsurface-scattering only works on parts that are actually diffusely lit! Meaning if you take a very high res normal map and have the model lit with a harsh light you will notice the skin going back to it's initial "stone"-look because of the lack of SSS.
What this means is that it's really hard to get a great looking skin from all kinds of light setups because there are so many factors that need to work for it (indirect light intensity, camera exposure, direct light intensity and it's direction).
So what we have to do is always make sure that every part of the skin is lit in some way or another (idea: adaptable SSS? stronger on darker parts, weaker on bright parts maybe?).
Another thing that comes with indirect Illumination is shadowing.
Shadowing is absolutely crucial for believable skin rendering. Especially when it comes to image-based-lighting and ambient occlusion. But certainly soft and hard shadow edges directly from a light source itself can make quite a difference!
Applying AO as a form of environment reflection shadowing is a must, however what we can also do is add a fake SSS to the shadowed parts to make the skin come to live just a bit more.
In shader code this looks like the following:
float3 strength = float3(0.4f, 0.15f, 0.13f); // Fake Color-Bleeding for AO
float3 colorBleedAO = pow(abs(AO), 1.0f - strength);
Diffuse += DiffuseAmbient * colorBleedAO;
And that's pretty much it about Skin.
The only thing I'm missing at this point is translucency for nostrils and ears, however this could be approximated using the translucency shading using an inverted AO map (http://www.crytek.com/download/2014_03_25_CRYENGINE_GDC_Schultz.pdf)
In the next part I will be talking about Eye Rendering and it's (still ongoing) challenges.
Here are a few more pictures to Showcase the Skin shading: