Forum: Poser - OFFICIAL


Subject: VSS Skin Test - Opinions

bagginsbill opened this issue on Apr 23, 2008 · 2832 posts


bagginsbill posted Mon, 05 May 2008 at 4:13 PM

Quote - can iask you for a simple way to explai to me how you make the cpecular without the specular value? is it a trick or what?

Yes its a trick. :)

Last year I moved away from skin shaders because I was failing miserably and I got frustrated.

I worked on simpler things, like car paint, glass, water.

Working with simple shiny materials, I learned a lot. I found that there are two very important rules - really important - when working with these.

  1. Conservation of Energy
  2. Fresnel effect

The conservation of energy is simple to understand, but sometimes hard to implement in a complex shader, such as skin. Working with simple stuff like glass or paint or milk, I learned how to do it well.

Basically, the reflection of a photon from a simple surface follows a simple statistical rule. There is a chance the photon immediately reflects off the surface (Reflection). If it does not, there is a chance it gets absorbed and re-emitted in a random new direction with a new color (Diffusion). If it does not, there is a chance it gets absorbed and becomes heat, no longer visible (Absorption - don't render it). If it does not, there is a chance that it travels through the material and comes out the other side (Refraction). That is a simplistic model, but it works for clear fluids and paint and metal.

For the purposes of reflections we have two types of nodes. The Reflect and Gather nodes (reflects other items in your scene) and Specular, Blinn, Phong, and Glossy nodes (reflects light from your light sources - simpler to calculate and often all that is necessary.) For the purposes of Diffusion, we have Diffuse and Clay. And for Refraction we can use transparency or we can use a Refract node.

(Velvet and Skin nodes combine Diffusion and Specularity - and do it badly. I never use those. You should not either.)

Now the sum of these probabilities is 1, since a photon has to do one of those four things. When we model a material in a shader, if we disobey this law, we get crap.

Basically, in most shaders, the Reflection_Value represents the probability of reflecting. The Diffuse_Value represents the probability of diffusion. The Refraction_Value represents the probability of refraction. The sum of these must be no more than 1. The probability of absorption is what is left after adding those three together.

So - am I getting to a point yet? Yes I am, soon.

Now it turns out that for many things (nearly everything in fact), the probability of reflection varies with the angle of incidence. If the photon is travelling straight into the surface, it is less likely to reflect than if it is travelling at a shallow angle, approaching the surface slowly. Imagine a bullet shot at a brick wall. It may go in, or it may ricochet. At a shallow angle, it will almost certainly ricochet. Light does the same. This phenomenon is called the Fresnel effect.

The various specular nodes have various models for this phenomenon. But none of them communicate their decision to the Diffuse node. As a result, we often have situations where the Specular node has decided that reflection is happening, while the Diffuse node also decides that Diffusion is happening. They do not cooperate and agree to split the incoming light between them, letting the specular node decide how much it should get based on Fresnel effect, and let the rest go to the Diffuse node.

This is why we get the yellow bloom on bad skin shaders. Both are firing and they should not.

What I have done is to use a mathematical trick to make the specular effect actually come from the Diffuse node!

I use a Blinn node (the best node for skin Fresnel effect) to find out how much light got reflected. Based on that, I blend the skin color with some WHITE. This blended color (peach to white) is sent to the Diffuse node, and I let it do its normal thing. But since I lie to it about the color, it sometimes gives us white highlights - precisely where the Blinn node was firing the most. Since I did not add the two together, I avoid the violation of the conservation of energy.

This is still not perfect and I am cheating like hell. But it is a much more realistic effect than naively adding together a Blinn and a Diffuse.

You might think that if we set Diffuse_Value + Specular_Value <= 1, it would work ok. But we cannot. There are situations where the probabily of Diffusion is near 0, because the probability of reflection is nearly certain. What then should we set Diffuse_Value equal to? There is no single good value. It must be a function, or we must trick it.

So that is how I do it, and that is why my shader behaves well under many different conditions.


Renderosity forum reply notifications are wonky. If I read a follow-up in a thread, but I don't myself reply, then notifications no longer happen AT ALL on that thread. So if I seem to be ignoring a question, that's why. (Updated September 23, 2019)