<html>

<head>
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Hair</title>
<meta name="Microsoft Theme" content="zero 111">
</head>

<body background="_themes/zero/zertxtr.gif" bgcolor="#000000" text="#FFFFFF" link="#669966" vlink="#6699CC" alink="#999999"><!--mstheme--><font face="Arial, Arial, Helvetica">


<div align="center">
  
  <!--msthemeseparator--><p align="center"><img src="_themes/zero/zerrulea.gif" width="600" height="10"></p>
  
  <h1><!--mstheme--><font color="#6699CC"><i>Hair</i><!--mstheme--></font></h1>
  <!--msthemeseparator--><p align="center"><img src="_themes/zero/zerrulea.gif" width="600" height="10"></p>
  <p align="justify">&nbsp;</p>
  <p><img border="0" src="images/HairSmall.jpg" width="256" height="247"></p>
  <p align="justify">&nbsp;</p>
  <p align="justify" style="line-height: 150%">The hair effect shows 
  procedurally generated geometry combined with anisotropic shading. It was 
  inspired by the <i>fur balls</i> seen in <i>lapsus</i> by <i>maturefurk</i>, a 
  demo that took 3<sup>rd</sup> place at the Assembly 2k demo competition. There 
  are two interesting things about this effect, namely physics and shading.</p>
  <p align="justify" style="line-height: 150%">First of all  physics, how to animate the hair 
  under influence of several forces. The two 
  forces used to animate the hair in this effect are gravity and inertia. 
  Gravity is simply a constant vector for all hairs whose direction describes 
  where the hairs should bend to and its magnitude describes how strong they 
  should bend. Inertia is simulated by  calculating the 2<sup>nd</sup> 
  derivative of a function that describes the current position of each hairs 
  end. What information is necessary to describe a hair or a ball of hairs 
  respectively? Well, 
  assuming that each hair starts at the origin and ends at some point on a unit 
  sphere we simply need a unitized normal for the hair direction when there is 
  zero gravity and inertia. To get some variation we should store the hair 
  length as well as a 1D texture coordinate. The 1D texture coordinate will be 
  used in conjunction with a 1D noise texture that gets stretched over the hairs 
  surface to model streaks - the streaks run along the hair -&nbsp;thus giving 
  each hair an individual touch. We use randomized values to setup each hair 
  in order to get a more natural look.</p>
  <p align="justify" style="line-height: 150%">It's time to generate the hairs. 
  Each hair has a fixed number of joints for which a position needs to be 
  calculated. We start at the origin and set the current hair direction to its 
  default. For the rest of the joints we sum up the current direction, the 
  global gravity vector and the hairs inertia vector to a new temporary 
  direction vector. This temporary direction vector needs to be 
  normalized. The position for each hair joint is then calculated by taking the 
  position of the previous joint and adding the normalized temporary direction 
  vector scaled by the hair length to it. The current hair direction is updated 
  by setting it to the normalized temporary direction vector.</p>
  <p align="justify" style="line-height: 150%">&nbsp;</p>
  <blockquote>
    <p align="justify" style="line-height: 150%">
    <font face="Courier New" size="2">vCurPos = ( 0, 0, 0 );<br>
    vCurDir = vHairDir;<br>
    <br>
    for 1 to NumJoints do<br>
    {<br>
&nbsp;&nbsp;&nbsp; vTempDir = vCurDir + vGravity + vHairInertia;<br>
&nbsp;&nbsp;&nbsp; Normalize( vTempDir );<br>
&nbsp;&nbsp;&nbsp; vCurPos += vTempDir * fHairLength;<br>
&nbsp;&nbsp;&nbsp; vCurDir = vTempDir;<br>
    }</font></p>
    <p align="justify" style="line-height: 150%">&nbsp;</p>
  </blockquote>
  <p align="justify" style="line-height: 150%">We connect all adjacent joints by 
  generating quads between them. In DirectX this can be done efficiently using 
  triangle strips. Note that multiple hairs can be put into one big triangle 
  strip by stitching them together (i.e. generating two degenerated&nbsp;triangles as connection pieces between two individual hairs) to increase rendering 
  performance. In order to generate a quad we actually need two position vectors 
  per joint - otherwise we would be generating lines (that is, triangles with an 
  area of zero!). By crossing the initial direction vector of each hair with the 
  global gravity vector and normalizing the result we get a vector that when 
  shortened by some amount (depending on how thick the hair should be) can be added to each joints position vector to get the second position vector. 
  At this point we should also prepare a 1D texture coordinate for both position 
  vectors so we can form vertices that can be send to the vertex shader later. 
  The 1D texture coordinate for the first position vector is simply the one 
  specified for each hair; the  1D texture coordinate for the second position 
  vector is the sum of the 
  first one and an arbitrary value which is constant for all hairs. The bigger 
  this arbitrary constant value the thinner the streaks.</p>
  <p align="justify" style="line-height: 150%">Now that we have generated the 
  geometry we need to define an appropriate vertex and pixel shader to give the 
  hair the proper look. Normal phong shading would work, though it wouldn't look 
  like hair but plastic. Therefore we use an anisotropic shading model to get 
  the kind of lighting we're after. <a href="#Ref1">[1]</a> and <a href="#Ref2">
  [2]</a> describe how this can be done in hardware using a 2D&nbsp; texture as a 
  lookup table for diffuse and specular intensities:</p>
  <p align="justify" style="line-height: 150%">&nbsp;</p>
  <!--mstheme--></font><table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" id="AutoNumber2">
    <tr>
      <td width="100%" colspan="2"><!--mstheme--><font face="Arial, Arial, Helvetica">
      <p style="line-height: 150%; margin-bottom: 4">
    <font face="Courier New" size="2">for a given point P on a surface</font><!--mstheme--></font></td>
    </tr>
    <tr>
      <td width="7%"><!--mstheme--><font face="Arial, Arial, Helvetica">
      <p style="line-height: 150%">
    <font face="Courier New" size="2">L</font><!--mstheme--></font></td>
      <td width="93%"><!--mstheme--><font face="Arial, Arial, Helvetica">
      <p style="line-height: 150%">
    <font face="Courier New" size="2">vector to light for P</font><!--mstheme--></font></td>
    </tr>
    <tr>
      <td width="7%"><!--mstheme--><font face="Arial, Arial, Helvetica">
      <p style="line-height: 150%">
    <font face="Courier New" size="2">T</font><!--mstheme--></font></td>
      <td width="93%"><!--mstheme--><font face="Arial, Arial, Helvetica">
      <p style="line-height: 150%">
    <font face="Courier New" size="2">surface tangent for P</font><!--mstheme--></font></td>
    </tr>
    <tr>
      <td width="7%"><!--mstheme--><font face="Arial, Arial, Helvetica">
      <p style="line-height: 150%">
    <font face="Courier New" size="2">V</font><!--mstheme--></font></td>
      <td width="93%"><!--mstheme--><font face="Arial, Arial, Helvetica">
      <p style="line-height: 150%">
    <font face="Courier New" size="2">vector to viewer for P</font><!--mstheme--></font></td>
    </tr>
    <tr>
      <td width="7%"><!--mstheme--><font face="Arial, Arial, Helvetica">
      <p style="line-height: 150%">
    <font face="Courier New" size="2">N</font><!--mstheme--></font></td>
      <td width="93%"><!--mstheme--><font face="Arial, Arial, Helvetica">
      <p style="line-height: 150%">
    <font face="Courier New" size="2">surface normal for P</font><!--mstheme--></font></td>
    </tr>
    <tr>
      <td width="7%"><!--mstheme--><font face="Arial, Arial, Helvetica">
      <p style="line-height: 150%">
    <font face="Courier New" size="2">R</font><!--mstheme--></font></td>
      <td width="93%"><!--mstheme--><font face="Arial, Arial, Helvetica">
      <p style="line-height: 150%">
    <font face="Courier New" size="2">reflected light vector for P</font><!--mstheme--></font></td>
    </tr>
  </table><!--mstheme--><font face="Arial, Arial, Helvetica">
  <p style="line-height: 150%">
    <img border="0" src="images/HairFig1.gif" alt="diffuse and specular intensities" width="336" height="131"></p>
  <p align="justify" style="line-height: 150%">&nbsp;</p>
  <p align="justify" style="line-height: 150%">As you can see from those 
  formulas the only two values we need for the texture lookup are <i>L<font face="Arial">•</font>T</i> and 
  <i>V<font face="Arial">•</font>T</i>. We pass the tangent vector for each 
  joint of a hair (that is, the current hair direction) along with the position 
  vector and the 1D texture coordinate to the vertex shader. Here we calculate&nbsp;<i>L</i> and 
  <i>V</i> for each vertex and dot them with <i>T</i> to get the proper texture 
  coordinates for a lookup into the texture. Care must be taken to map <i>L<font face="Arial">•</font>T</i> and 
  <i>V<font face="Arial">•</font>T</i> from [ -1, 1 ]&nbsp; to [ 0, 1 ] -- 
  via <i>x' = 0.5 <font face="Arial">• </font>( 1 + x )</i> -- since the result 
  of a dot product for two normalized vectors is in [ -1, 1 ] but the 
  corresponding texture space is [ 0, 1 ]. </p>
  <p align="justify" style="line-height: 150%">The pixel shader finally does the 
  lighting. It fetches the diffuse and specular intensity from the <i>anisotropy 
  texture</i> map as well as the color for the streaks from the 1D noise 
  texture. The colors and intensities are modulated and combined in the 
  following way:</p>
  <p align="justify" style="line-height: 150%">&nbsp;</p>
  <!--mstheme--></font><table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" id="AutoNumber3">
    <tr>
      <td width="100%"><!--mstheme--><font face="Arial, Arial, Helvetica">
  <font face="Courier New" size="2">diffuse&nbsp;color&nbsp; = diffuse&nbsp;intensity&nbsp; 
      • diffuse&nbsp;hair color&nbsp; • streak color<br>
      specular color = specular intensity • specular hair color • streak color<br>
      final color&nbsp;&nbsp;&nbsp; = diffuse color + specular color</font><!--mstheme--></font></td>
    </tr>
  </table><!--mstheme--><font face="Arial, Arial, Helvetica">
  <p align="justify" style="line-height: 150%">&nbsp;</p>
  <p align="justify" style="line-height: 150%">Note that the diffuse and 
  specular hair color can be adjusted in the settings dialog in the Effect 
  browser as well as the ambient, diffuse and specular light settings and the 
  gloss factor. Those directly influence the diffuse and specular intensities 
  the pixel shader fetches from the <i>anisotropy lookup texture</i> map.</p>
  <p align="justify" style="line-height: 150%">&nbsp;</p>
  <h3><!--mstheme--><font color="#6699CC">References<!--mstheme--></font></h3>
  <!--mstheme--></font><!--msthemelist--><table border="0" cellpadding="0" cellspacing="0" width="100%">
    <!--msthemelist--><tr><td valign="baseline" width="42"><img src="_themes/zero/zerbul1a.gif" width="15" height="15" hspace="13" alt="bullet"></td><td valign="top" width="100%"><!--mstheme--><font face="Arial, Arial, Helvetica">
    <p align="justify" style="line-height: 150%; margin-bottom:4">
    <a name="Ref1">[1]</a> Wolfgang Heidrich and Hans Peter Seidel.
    <a href="http://www9.informatik.uni-erlangen.de/eng/research/rendering/anisotropic/">
    &quot;Anisotropic Reflections in OpenGL&quot;</a> <!--mstheme--></font><!--msthemelist--></td></tr>
    <!--msthemelist--><tr><td valign="baseline" width="42"><img src="_themes/zero/zerbul1a.gif" width="15" height="15" hspace="13" alt="bullet"></td><td valign="top" width="100%"><!--mstheme--><font face="Arial, Arial, Helvetica">
    <p align="justify" style="line-height: 150%; margin-bottom:4">
    <a name="Ref2">[2]</a> Mark J. Kilgard (NVIDIA). <a href="http://developer.nvidia.com/">&quot;Hardware 
    Accelerated Anisotropic Lighting&quot;</a><!--mstheme--></font><!--msthemelist--></td></tr>
  <!--msthemelist--></table><!--mstheme--><font face="Arial, Arial, Helvetica">
  <p align="justify">&nbsp;</p>
  <!--webbot bot="Include" U-Include="footer.htm" TAG="BODY" startspan --><!--msthemeseparator--><p align="center"><img src="_themes/zero/zerrulea.gif" width="600" height="10"></p>
<p></p>
<p></p>
  <dl>
    <div align="center">
      <center>
      <dt>Last update on
      2002-03-17</dt>
      </center>
    </div>
    <div align="center">
      <center>
      <dd>
      <p align="center">&nbsp;</dd>
      </center>
    </div>
    <div align="center">
      <center>
      <dt>Meshuggah Demo and Effect browser.</dt>
      </center>
    </div>
    <div align="center">
      <center>
      <dt>Copyright © 2001, 2002
      <a href="mailto:carsten.wenzel@gmx.net?subject=Meshuggah Demo and Effect browser">Carsten Wenzel</a>.</dt>
      </center>
    </div>
    <div align="center">
      <center>
      <dt>All rights reserved.</dt>
      </center>
    </div>
  </dl>

<!--webbot bot="Include" i-checksum="22998" endspan --></div>


<!--mstheme--></font></body>

</html>
