Analysis of Marschner’s model

Here is my understand regarding the azimuthal component of Marschner’s model. All the analysis are carried on a cross section of the hair.

I posted two figures for later reference. Figure 1 shows the scattering geometry, and Figure 2 the cross section.

Figure 1: Scattering geometry

Figure 2: Geometry for scattering from a circular cross section

The goal of Marschner’s model is to solve for the outgoing intensity. Please refer to Figure 2 first, the incoming ray has been scattered into three ways, some part of the energy has been reflected directly; some enters the hair, and leaves at the other side of the surface; some enters the hair, reflected at the inner surface and final refracted out. Likewise, when given the outgoing angle phi(the relative azimuth phi_r – phi_i), we can reverse this process to find out the directions of light that contribute to the outgoing intensity. For instance, in Figure 3, the intensity of the outgoing direction (in blue) is the contribution from three (not necessary to be exactly three)incoming beams (in  red).

Figure 3: Light from three paths that contribute to one outgoing direction

Back to the second figure, setting aside attenuation for the moment, power from a small interval dh in the incident beam is scattered into an angular interval d/phi in the exitant intensity distribution


To complete this equation, we have to take into account attenuation caused by absorption and reflection by introduce an attenuation factor A(p, h) in front of the intensity contributed by a path.

where p = 0 stands for surface reflection R, 1 for refractive transmission TT, and 2 for internal reflection TRT. Refer to Figure 3 for a visualization of the three paths.

Consider Path 1 in Figure 3, the light reflects directly, so the Fresnel factor can be applied to account for the reflected energy, thus A(0, h) = F(eita, gamma_i);

For Path 2, the light first undergoes refraction, thus the energy enters the hair should be (1-F(eita, gamma_i)) multiple the original energy. Then it travels a distance of 2*cos(gamma_t) (with the radius of the hair being unit length), assume sigma_a to be the volumn absorption per unit length, the absorption factor T should be exp(…), finally, it refracts out of hair, so (1-F(eita, gamma_t)) is used to account for the refracted energy.

Path 3 is similar to Path 2, except that the light reflected once at the inner surface of hair, and travels two times of the distance as it in Path 2. Personally, I would write A(2, h) as

rather than

given by the paper, where p = 2.

One more thing to mention. Before we carry on analysis, we have to project the scattering geometry from 3D to 2D, as well as various parameters, including the index of fraction, and each internal segment should be lengthened by a factor of 1/cos(theta_t). 

 The End


Car racing demo using Irrlicht

This game is developed for use as a demo in my presentation on Irrlicht engine at the Technique Introduction Seminar within our laboratory.

Have a look at first.

The city model used in this demo comes from the website

in the format of 3DS, and the two car models were borrowed from our lab, loaded as Obj file in the demo. Actually, I prefer Obj files than 3DS as I can use a text editor to read the content of it.

I use Irrlicht as the 3D engine. Why chose it? It’s simple to install and easy to use. I also studied Ogre3D three weeks in total, and found it easy to take use of the ready-made functions, but extremely difficult when come to a need to extend the basics.

Help information that should be included in this demo:

Press W/S for forward/backward, A/D for strafing left/right, Control for speed up.

The game contains three scenes, the countdown scene from three to one, then shows go, the main racing process and the finishing scene where the camera is placed near the finishing line and points to the car that arrives earlier.

The development process of the racing scene:

Step 1. Place the model

The loaded models did not show at the proper places, so I had to manually change the positions of them. I placed the two cars side by side on a bridge in the city model. Here I want to talk about how I achieved that. I changed the initial position of one car model little by little until it got to the middle of the road. Every time after I changed the position, I had to compile the program to see where it was until it looked fine to me. I do not know any better ways to do this. All I can think of is to display the position of the camera so by moving the camera to a suitable position for a car, I can read off the coordinates in the world space, and then use this data to indicate the position of the car. If you have better ideas to handle this, please email me.

Step 2. Define the movement of the car.

I followed the convention of most game controls with W forward, S backward, A strafe left, R strafe right. At first, the four kinds of movement are defined in the world space, but soon I found a bug. If the car was placed at the XZ-plane and initially heads to the +x direction and turns an angle, say -90 degrees, it would head to –z direction. Since the movement defined for the key W is relative to the world space, pressing W only moves the car toward +x direction, but when the car faces –z direction, the expected forward movement should toward negative z, that is not what the W key does. In order to solve this, I introduced a direction vector for the car, every time the car turns, the direction vector turns as well, and the W key is defined to move the car along the direction vector, and the S key opposite. In this way, I managed to move the car along the direction it faces with W and S keys.

Step3. Define the movement of the competitor car.

This is the part that I am not satisfied with. Since the track contains a curve that connects two orthogonal straight roads. What I thought is the car should turn a total degree of 90 between it enters the curve and leaves the curve. The curve has actually been divided into four straight segments. I confirmed the coordinates at each connecting point using the same way as in Step 1 and assigned a 90/4 degrees-turn during each segment. It needs tremendous work to adjust the movement of the car to make it looks natural because the difference in the length of each segment requires assigning different degrees of direction change. For simplicity, the 90/4 degrees was assigned to each segment.

I included the binary file and the source file, only one cpp, through the link. You will find it really difficult to read the source file since I am too lazy to structure it.