Marschner Shader Part II
In my last post I mentioned two functions that are needed to represent the hair model as depicted in Marschner’s paper.
S = SR + STT + STRT,
Sp = Mp (q i , q r ) x Np (q d , f d ) for P = R, TT, TRT.
M component
This is actually just a probability density function and the best choice here is to use a Gaussian distribution (or normal distribution).
And the M components are as follows:
- MR (q h ) = g( Beta R , q h – Alpha R).
- MTT (q h ) = g( Beta TT , q h – Alpha TT).
- MTRT (q h ) = g( Beta TRT , q h – Alpha TRT).
N component
The N component is actually a bit tricky to compute. Here are all the main steps:
- Convert to Miller-Bravais index.
This is done in order to change the index of refraction to 2D physics, so that the optics of a 3D cylindrical fiber may be reduced to the 2D analysis of the optics of its cross-section.
After looking into Snell’s Law we define the indexes of refraction as:
- Solve a cubic equation
Remember this picture:
We need to find out who the incident angles are, and we can approximate the solution for this equation as:
- Solve Fresnel equation
Fresnel equation is used in order to simulate the reflection model from within the attenuation
- Find out the absorption factor
This is actually quite straightforward, just:
- The attenuation factor
This is obtain combining both the reflection and the absorption factor, hence the “Attenuation by absorption and reflection” model from Marschner’s paper.
where the first derivative is
- The N component (finally)
and the N are
- NR (q d , f d ) = NP (0, q d , f d ).
- NTT (q d , f d ) = NP (1, q d , f d ).
- NTRT (q d , f d ) = NP (2, q d , f d ).
For the last component Marschner proposes a more complex model in order to avoid singularities, but for my implementation I couldn’t tell any improvement so I stuck with the simpler version of NTRT.
The whole model
As a sum up this is the whole Marschner hair model in just an equation:
Hope I managed to keep everything simple and explicit alike.
Hi!
Just three quick comments.
First: are you sure the Bravais index used in Marschner’s (and in fiber rendering in general) is the same as the Miller-Bravais index? I have not read much about the second one, but they seem to me as completely different things…
Second: When you compute the derivative of phi with respect to h, you have used the polynomial approximating phi. Which is great, as far as I can tell, but you can actually compute the derivative of the real phi instead of the derivative of the approximation. I don’t know which of the two options is better though, maybe it’s better to be consistent and use the approximation all the time.
Third: You say that N_TRT is N_p(2,q_d,f_d). I am afraid this is not this way, because some caustics smoothing is required. This is explained in the “Approximation for TRT” section of the paper (page 8 to the right).
Sorry for being so schematic, I’m in a hurry right now 🙂
By the way, I think you’ve implemented Marschner’s. May I ask you a question? The input angles fd and qd are in the range 0..pi (since we use cosines to index in the lookup textures). However, the first thing we need to do is to use qd to compute the Bravais’ index, which only makes sense for angles in the -pi/2..pi/2 interval. Could you tell me how has you solved this?
Hello,
Thanks for your comments.
First: From what I have read Bravais indices are a modification of the Miller indices. However apart from that definition I couldn’t find any relevant link to put in the post, so I went with the best next thing which I considered the Miller indices.
Second: I chose to stick with the approximation to be consistent, but I think I am going to try to compute the derivative of the real phi as well to see if there is any difference.
Third: I considered N_TRT to be N_p(2,q_d,f_d) because the lookup textures looked the same for this and for the N_TRT defined in the “Approximation for TRT” section of the paper. Furthermore I did this because in this report they did the same approximation and had good visual results.
I have implemented Marschner (a C# projects that computes the lookup textures), but I think I still have some problems. I am going to attach the code of the project in my next post and put a video with the results in CS so far.
About the cos for the second texture lookup, I think that both the fq and qd angles are in range -pi/2..pi/2, and sin should be used instead. Because qr and qi are in range -pi/2..pi/2 so qd = (qr – qi) / 2 is still in range -pi/2..pi/2. And the fi and fr are in range 0..pi/2 and their difference fr – fi is in -pi/2..pi/2. However generating the lookup texture with sin instead of cos makes a picture that is mirrored so there might be redundant to use sin after all.
I am not sure when I will post the project with code, because I want to modify it further, but if you want you can send me an email and I’ll attach you the archive.
Hello again, thanks you very much for your prompt answer and your offer of sending me your code 🙂 I have sent you an e-mail to what I expect to be your yahoo account. Not sure about whether it is or not because I didn’t get it from this blog (couldn’t find any contact details in here…).
Updated the About page so that it contains my email as well.
Hi, a nice post!
One question: in the paper, they gave the absorption factor:exp(-2*Sgima_a(1+cos(2*Gamma_t))) as each internal path segment is “2+2*cos(2*Gamma_t)”.
But according to the figure, it seems each path segment is simply “2*cos(Gamma_t)”
I saw that the one you give is “2 + 2*cos(Gamma_t)”
Hi, thanks!
You can try both of them see what gives better visual results, in the end that’s all that matters. If I used a different factor from the paper then probably that’s the reason.
Moreover, I ended up using Kajiya and Kay’s model for hair as well, because for my model I couldn’t really see any difference.
I think I will try to add some self-shadows during this summer, see how that looks.
Detailed illustration. but I have difficulty in understanding how you generalized the parallel component for the Fresnel factor. why the positions of eita1 and eita2 in the perpendicular component exchanged in the parallel component? and what’s the purpose to average the square of these two factors? Thank you in advance.
For the graphics part have a look at:
Click to access a_survey_of_shading_models.pdf
If you are interested in the physics behind, check:
Click to access fresnel_brewster.pdf
http://cnx.org/content/m12904/latest/