home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / FAQSYS18.ZIP / FAQS.DAT / OTMPHONG.DOC < prev    next >
Text File  |  1995-04-08  |  24KB  |  516 lines

  1.  
  2.         OTMPHONG.DOC - A new approximation technique for the Phong
  3.                        shading model based on linear interpolation
  4.                        of angles
  5.  
  6.         released 3-30-95
  7.         by Voltaire/OTM [Zach Mortensen]
  8.  
  9.         email -
  10.         mortens1@nersc.gov
  11.  
  12.         IRC -
  13.         Volt in #otm, #coders
  14.  
  15.  
  16. INTRODUCTION
  17.  
  18.                 Realtime phong shading has always been a goal for 3d
  19.         coders, however the massive amount of calculations involved
  20.         has (until recently) hampered progress in this area.  When I
  21.         first heard the term 'realtime phong shading' mentioned about 6
  22.         months ago, I laughed to myself at what I perceived was an
  23.         oxymoron.  In my experience at the time (derived from reading
  24.         several 3d documents), phong shading required a tremendous
  25.         amount of interpolation and one square root per pixel.  Even
  26.         with lookup tables for the square root function, there was no
  27.         way that this algorithm would be fast enough to use in
  28.         realtime.  Early reports from other coders attempting realtime
  29.         phong shading proved this, the fastest code I heard of could
  30.         draw around 1500 triangles per second.
  31.  
  32.                 Phong shading never really was a goal of mine.  I am a
  33.         pretty lazy person, I could think of a thousand ways I would
  34.         rather spend my time than implementing an inherently slow
  35.         algorithm in my code and trying to optimize it.  Until about a
  36.         week ago that is, when I received a little demo called CHEERIO
  37.         by Phred/OTM.  Phred and I have been good friends for quite
  38.         awhile, and we both write vector code.  We have helped each
  39.         other improve the speed of our code dramatically by sharing our
  40.         ideas, 2 heads are definitely better than 1!  Anyway, there
  41.         were rumors flying around that CHEERIO was phong shaded, when
  42.         in reality it was really nice gouraud shading.  I took a close
  43.         look and...well, it looked like phong but Phred wasn't around
  44.         to correct us, so I went on believing he had coded a phong fill
  45.         that was as fast as my gouraud fill.  Part of the reason Phred
  46.         and I have made our code so fast is competition, neither of us
  47.         can stand being outdone by the other.  So whether I wanted to
  48.         or not, I had to come up with a fast phong fill SOON if I were
  49.         to save face.
  50.  
  51.                 The fastest method I knew of was using a Taylor series
  52.         to approximate color values.  This method involves a fairly
  53.         fast inner loop with a lot of precalculation.  It also requires
  54.         a thorough knowledge of calculus.  Believe me, doing Taylor
  55.         series on your homework is a lot easier than trying to
  56.         implement one in the real world for some strange reason.  So
  57.         that is where I started, I was deriving the Taylor
  58.         approximation for phong shading when I stumbled upon what
  59.         seemed to me an obvious shortcut that would make phong filling
  60.         nearly as fast as gouraud filling.  I also believe I am the
  61.         first to come up with this method, since I have seen no
  62.         articles about it, and I have yet to see realtime phong shading
  63.         in a demo or game.
  64.  
  65.                 OK, now on to the fun stuff...
  66.  
  67.  
  68.  
  69. THE PHONG ILLUMINATION MODEL
  70.  
  71.  
  72.                 This is not a text on phong illumination, but on phong
  73.         SHADING.  They are two very different things.  Whether you use
  74.         phong shading or not, you can use phong illumination with your
  75.         lambert or gouraud shading to make your colors look more
  76.         realistic.  I don't want to get into how this formula is
  77.         derived, so I will just give you the low down dirty goods.
  78.  
  79.  
  80.         color = specular + (cos x) * diffuse + (cos x)^n * specular
  81.  
  82.  
  83.                 Make sure you set up your palette in this way. In a
  84.         nutshell, the ambient component defines the color of an object
  85.         when no light is directly striking it, the diffuse component
  86.         defines the color of the object, and the specular component
  87.         defines the color of the highlight made when light strikes the
  88.         object directly.  x should have a range of 0 to 90 degrees,
  89.         since that is the range of angles possible when light
  90.         intersects a visible plane.  The power n in the specular
  91.         component defines certain attributes about the material, the
  92.         greater the power n, the shinier the material will appear to be
  93.         (i.e. the specular highlight will be smaller and brighter as n
  94.         increases).
  95.  
  96.  
  97.  
  98. THE PHONG SHADING MODEL
  99.  
  100.  
  101.                 The idea behind phong shading is to find the exact
  102.         color value of each pixel.  In its most common form, the phong
  103.         shading model is as follows:
  104.  
  105.         1) determine a normal vector at each vertex of a polygon, the
  106.            same normal vector used in gouraud shading.
  107.  
  108.         2) interpolate normal vectors along the edges of the polygon.
  109.  
  110.         3) interpolate normal vectors across each scanline, so you have
  111.            one normal vector for each pixel in the polygon.
  112.  
  113.         3) determine the color at each pixel using the dot product of
  114.            the normal vector at that pixel and the light vector, the
  115.            same method used in gouraud and lambert shading.  Since the
  116.            interpolated normals are not of constant length, this step
  117.            requires a square root to find the length of the normal.
  118.  
  119.  
  120.                 This shading model produces impressive results.  A new
  121.         color is calculated for each pixel, and the color gradient
  122.         across a plane is non linear.
  123.  
  124.                 However it is also VERY SLOW if implemented as it is
  125.         shown here.  In order to linearly interpolate a vector, one
  126.         must interpolate x, y, and z coordinates.  This task is not
  127.         nearly as time consuming as the dot product, which requires 4
  128.         multiplies, 2 adds, a divide and a square root per PIXEL.  A
  129.         few optimizations can be performed that eliminate one multiply
  130.         and replace the square root with a table lookup, but 3
  131.         multiplies and a divide per pixel are far too slow to be used
  132.         in realtime.
  133.  
  134.  
  135. OPTIMIZING THE PHONG SHADING MODEL
  136.  
  137.  
  138.                 Lets mathematically break down the phong shading model.
  139.         After all is said and done, you are left with the dot product
  140.         of the pixel normal vector and the light vector divided by the
  141.         product of the magnitudes of these two vectors.  Another way to
  142.         express this value is (cos Θ), where Θ is the smallest angle
  143.         between the two vectors.
  144.  
  145.         u = pixel normal vector
  146.         v = light vector
  147.  
  148.         u dot v = cos Θ * |u| * |v|
  149.  
  150.                  u dot v
  151.         cos Θ = ---------
  152.                 |u| * |v|
  153.  
  154.                 So the dot product of a normal vector and a light vector
  155.         divided by the product of the magnitudes of the two vectors is equal
  156.         to the cosine of the smallest angle between the two vectors.  This
  157.         should be nothing new, it is the same technique used to find color
  158.         values in the lambert and gouraud shading techniques.  Lets attempt
  159.         to graphically represent what is going on with phong, gouraud and
  160.         lambert shading.
  161.  
  162.  
  163.                                 graph of y = cos Θ (*)
  164.         |
  165.         |
  166.         |*    *
  167.         |          *
  168.         |             *
  169.         |                *
  170.         |                   *
  171.         |                     *
  172.         |                       *
  173.         |                         *
  174.       y |                          *
  175.         |                           *
  176.         |                            *
  177.         |                             *
  178.         |                              *
  179.         |                               *
  180.         |                                *
  181.         |                                 *
  182.         |                                  *
  183.         |                                   *
  184.         +------------------------------------------
  185.                             Θ
  186.  
  187.                 The phong shading model states that the intensity of light
  188.         at a given point is given by the dot product of the light and normal
  189.         vectors divided by the product of the magnitudes of the two vectors.
  190.         Flat shading is the roughest approximation of this, planes are
  191.         rendered in a single color which is determined by the cosine of the
  192.         angle between the plane's normal vector and the light vector.  If
  193.         we graph the intensity of light striking flat shaded planes, we
  194.         should find that they roughly form a cosine curve, since the color
  195.         values at certain points are determined by the cosine of the angle
  196.         between two vectors
  197.  
  198.  
  199.                           graph of Intensity = cos Θ (*)
  200.         |      flat shading approximations of light intensity shown as (X)
  201.         |
  202.         |*XXXX*XX               dΘ  (angle between normal vectors)
  203.         |          *       -------------
  204.         |        XXXXX*XXXX            |
  205.         |                *             | dI  (change in intensity)
  206.         |                   *          |
  207.         |                  XXX*XXXXXX  |
  208.         |                       *
  209.       I |                         *
  210.         |                          *
  211.         |                           *XXXXXX
  212.         |                            *
  213.         |                             *
  214.         |                              *
  215.         |                               *
  216.         |                                *
  217.         |                                 *XXXXX
  218.         |                                  *
  219.         |                                   *
  220.         +------------------------------------------
  221.                              Θ
  222.  
  223.                 This graph tells us something that we already know by
  224.         practical experience, that flat shading is very inaccurate for large
  225.         values of dΘ, and much more accurate for small values of dΘ.  This
  226.         means that the shading appears smoother when the angle between
  227.         normals (and therefore between planes) is very small.
  228.  
  229.                 Now lets consider gouraud shading.  Gouraud shading is a
  230.         linear interpolation of color between known intensities of light.
  231.         The known intensities in gouraud shading are defined at each
  232.         vertex, once again by use of the dot product.  In this case, the
  233.         normal vector at each polygon vertex is the average of the normal
  234.         vectors (the ones used in flat shading) for all planes which share
  235.         that vertex.  Normals of planes which are greater than 90 and less
  236.         than 270 degrees from the plane containing the vertex in question are
  237.         not considered in the average because the two planes are facing
  238.         away from each other.  If we plot interpolated intensities used in
  239.         gouraud shading against the cosine curve, it is evident that gouraud
  240.         shading is a much more accurate approximation than flat shading.
  241.  
  242.  
  243.                         graph of Intensity = cos Θ (*)
  244.         |        interpolated light intensities shown as (X)
  245.         | ---------------------------------+
  246.         |*X   *                            | in this region, the linear
  247.         |  XXXX ---*--------+              | approximation is always going to
  248.         |      XXX    *     | dI (error)   | be inaccurate without a very
  249.         |         XXXX --*--+              | small value for dΘ
  250.         |             XXX   *              |
  251.         |                XXXXX*  --------------+
  252.         ||____________________|X*              |
  253.       I |        dΘ              X*            |
  254.         |                         X*           | in this region, a gouraud
  255.         |                          X*          | approximation is nearly
  256.         |                           X*         | perfect because cos x is
  257.         |                            X*        | nearly linear
  258.         |                             X*       |
  259.         |                              X*      |
  260.         |                               X*     |
  261.         |                                X*    |
  262.         |                                 X*   |
  263.         |                                  X*  |
  264.         +------------------------------------------
  265.                            Θ
  266.  
  267.                 This graph tells us that gouraud shading is very accurate
  268.         as Θ->90.  However, if Θ is small and dΘ is large, gouraud shading
  269.         will look like an obvious linear approximation.  This can be avoided
  270.         by using smaller values of dΘ (i.e. use more polygons to fill in the
  271.         gaps in the interpolation).  With enough polygons, gouraud shading
  272.         can be 100% correct.
  273.  
  274.                 Phong shading is the most correct method of shading because
  275.         it is not an approximation, distinct colors are determined for each
  276.         pixel.  These values follow the cosine curve exactly, because the
  277.         intensity of each pixel was calculated using a dot product, which
  278.         eventually yields the cosine of the angle between the plane at 
  279.         that pixel and the light vector.  If we plot phong shading 
  280.         intensities with the cosine curve, we find that the values 
  281.         follow the function exactly.
  282.  
  283.  
  284.                         graph of Intensity = cos Θ (*)
  285.         |            phong light intensities shown as (X)
  286.         |
  287.         |X    X
  288.         |          X
  289.         |             X
  290.         |                X
  291.         |                   X
  292.         |                     X
  293.         |                       X
  294.         |                         X
  295.       I |                          X
  296.         |                           X
  297.         |                            X
  298.         |                             X
  299.         |                              X
  300.         |                               X
  301.         |                                X
  302.         |                                 X
  303.         |                                  X
  304.         |                                   X
  305.         +------------------------------------------
  306.                              Θ
  307.  
  308.                 Once again, shadings calculated using the phong model follow
  309.         the cosine curve, because the dot product between the normal vector
  310.         at each pixel and the light vector can be simplified to a function
  311.         involving cos Θ.
  312.  
  313.  
  314. TAYLOR APPROXIMATIONS
  315.  
  316.                 Now that we know a function which gives the intensity of
  317.         light at a given pixel, we need to find a fast way to evaluate that
  318.         function.  Most people seem to know that Taylor series can be used
  319.         for phong shading, but I have never met anyone that was able to
  320.         tell me that the cosine function would be the function that is
  321.         approximated.  The fact that vector coders are afraid of math is
  322.         disturbing to me.
  323.  
  324.                 The Taylor approximation for cos(x) is given by the following
  325.         series:
  326.  
  327.                     x^2   x^4   x^6                      x^(2n)
  328.         cos x = x - --- + --- - --- + ... + (-1)^(n-1) * ------
  329.                      2!    4!    6!                       (2n)!
  330.  
  331.         Actually I think that is a Maclaurin series, which is nothing more
  332.         than a Taylor series expanded about the point x = 0.  In any case,
  333.         you can use any number of terms in a Taylor series to approximate
  334.         a function.  The more terms you use, the more accurate your
  335.         approximation will be...and the slower your approximation will be.
  336.         The first two terms of the series for cos x are sufficient to give
  337.         an accurate approximation from x = 0 to x = 90, which are the limits
  338.         of Θ between the light and visible facets.
  339.  
  340.                 This is about as far as I got with the Taylor approximation
  341.         method for phong shading.  Once I got to this point, the proverbial
  342.         light bulb clicked on inside my head, and I forgot all about Taylor
  343.         series because I came up with a faster method.
  344.  
  345.  
  346. LINEAR INTERPOLATION OF ANGLES
  347.  
  348.                 To set the scene for you, I was riding the bus to school
  349.         about at about 8:00 in the morning when I thought I would do a bit
  350.         of work on the phong algorithm.  The bus ride is about 30 minutes and
  351.         is usually devoid of any excitement, so I whipped out my trust pad
  352.         of graph paper and started grinding out formulas.  I got really
  353.         excited when I arrived at the Taylor approximation, but I just about
  354.         jumped through the roof when this thought entered my mind.
  355.  
  356.                 I realized that the Taylor approximation for phong shading
  357.         basically interpolates values along the curve I = cos(Θ) just as
  358.         gouraud shading linearly interpolates values, except the values for
  359.         phong shading happen to fall directly ON the cosine curve.  The
  360.         problem is that the cosine curve is not linear, therefore phong
  361.         interpolation is much more complicated than gouraud interpolation.
  362.  
  363.                 Then I stepped back and looked at the problem from another
  364.         angle (punny).  If it were possible to interpolate some other value
  365.         related to cos(Θ), and if this other value changed in a linear
  366.         fashion, it would be possible to create a lookup table that related
  367.         cos(Θ) to this other value.  After a bit of deep thinking, I realized
  368.         that I was staring right at such a value, Θ!  The angle between the
  369.         light vector and the normal vector at each vertex of a plane
  370.         changes in a linear fashion as you go from one vertex to the next, and
  371.         from one edge of the plane to the next across each scanline.
  372.  
  373.                 As soon as it hit me, this idea made perfect sense.  The phong
  374.         shading model calls for normal vectors to be linearly interpolated
  375.         from vertex to vertex and from edge to edge.  When I thought about
  376.         this a bit further, it seemed totally ridiculous.  The actual
  377.         <x,y,z> coordinates of these normals do not matter one bit, only
  378.         the angle between the vector defined by these coordinates and the
  379.         light vector.  Why interpolate 3 coordinates per pixel when they are
  380.         just an intermediate step in finding the angle between two vectors?
  381.  
  382.                 So angular interpolation eliminates the interpolation of a
  383.         whole vector.  But that's not all, it also eliminates the dot product
  384.         which was previously needed to find the cosine of the angle between
  385.         the normals and the light.  Without the dot product or vector
  386.         interpolation,  there is nothing left of the traditional method of
  387.         phong shading.  All that needs to be done is interpolate angles
  388.         across the plane, and look up the cosine of those angles in a lookup
  389.         table.  Once you know the cosine, the rest is easy.
  390.  
  391.                 Using this method, an existing gouraud fill can be converted
  392.         to a phong fill very very easily.  Instead of interpolating colors
  393.         across the plane, interpolate angles instead.  If you are smart about
  394.         the way you express your angles, they can be represented in a single
  395.         byte.  Remember that the only possible values for the smallest angle
  396.         between a normal vector and a light vector are 0 to 90 degrees.
  397.  
  398.                 After you have interpolated an angle and looked up its
  399.         cosine, all you need to do is plot a pixel of the correct color.
  400.         The color calculations for each pixel are the same as those for
  401.         lambert and gouraud shading.  Multiply the cosine by the number of
  402.         colors in the gradated palette range and add the result to the base
  403.         color of the range.
  404.  
  405.                 Of course, you need to determine the angle between the light
  406.         and the normal vectors at each vertex.  This can be accomplished by
  407.         the inverse cosine function.  By taking the inverse cosine of the
  408.         cosine, you get the angle as a result.  Try to remember your trig
  409.         classes.
  410.  
  411.  
  412. LIMITATIONS
  413.  
  414.                 Angular interpolation is correct in 99% of all possible
  415.         cases.  The only cases when it will not be correct is when the
  416.         angles at any two or more vertices are equal.  Interpolated vector
  417.         phong shading will display a specular highlight inside the plane in
  418.         such a case, but interpolated angle phong shading will render the
  419.         plane in a solid color because the difference between the angles at
  420.         the vertices is 0, there will be no change in the angle across the
  421.         plane.
  422.  
  423.  
  424. CRITICISM AND RESPONSE SESSION
  425.  
  426.                 The preliminary release of demos incorporating this technique
  427.         were met with a bit of criticism, most of which was caused by
  428.         ignorance.  Here are a few common criticisms of this technique and
  429.         my responses.
  430.  
  431.  
  432.         "You are interpolating something linearly, and linear interpolation
  433.         is gouraud shading"
  434.  
  435.         Do your homework.  The phong model calls for linear interpolation of
  436.         normal vectors, and it is obviously not gouraud shading.
  437.  
  438.  
  439.         "It looks a lot like gouraud shading"
  440.  
  441.         Yes it does.  Refer to the section where I plotted intensities based
  442.         on various shading techniques, and take a look at the graphs of
  443.         Intensity vs. Θ.  You will find that for a small dΘ, gouraud shading
  444.         looks very much like phong shading.  However, phong shading can
  445.         achieve this result with a much larger dΘ, which means less facets.
  446.  
  447.  
  448.         "I see no specular highlight"
  449.  
  450.         The first version I released used a linear palette, not a palette
  451.         based on the phong illumination model.  Without the phong
  452.         illumination model, it is very hard to make specular highlights look
  453.         correct.  The palette has now been corrected to conform to the phong
  454.         illumination model.
  455.  
  456.  
  457.         "You still can't get a highlight in the center of a single polygon"
  458.  
  459.         Well, I think that the speed of this method is a reasonable tradeoff.
  460.         Specular highlights appear between polygons with this method, and
  461.         the difference is not too noticeable.
  462.  
  463.  
  464.         "The specular highlights are no different than gouraud specular
  465.          highlights"
  466.  
  467.         Take a closer look.  With gouraud shading, specular highlights are
  468.         gradated in a linear manner.  With phong shading, the gradation of
  469.         colors is nonlinear because it follows the cosine curve.
  470.  
  471.  
  472. CLOSING COMMENTS
  473.  
  474.                 Angular interpolated phong shading is new as far as I know.
  475.         If you decide to use this technique in any of your code, please give
  476.         me appropriate credit.  I am not asking for a cut of your royalties,
  477.         just to have my name mentioned somewhere.  I have always made it a
  478.         point to give credit where credit is due, and I would appreciate if
  479.         you would do the same.  Someone along the line actually has to put in
  480.         some hard work to develop the algorithms that we all use.
  481.  
  482.  
  483. GREETS
  484.  
  485.         Siri                    - you are the love of my life
  486.         OTM                     - I...have...nothing...to...say
  487.         Phred/OTM               - good vector conversation
  488.         Rich Beerman            - our game will rule
  489.         Darkshade               - for always being helpful
  490.         THEFAKER/S!P            - infinite humility :)
  491.         Sami Nopanen            - cacheman...
  492.         Tran and Daredevil      - PMODE/W, gotta love it
  493.         VLA                     - for not releasing any more 3d docs :)
  494.  
  495.         all my #coders buddies
  496.         bri_acid
  497.         MainFrame
  498.         StarScream
  499.         ae-
  500.         fysx
  501.         phoebus
  502.         doom
  503.         Moomin
  504.         Simm
  505.         LiveFire
  506.         MArtist
  507.         Zed-
  508.         Omni
  509.         ior
  510.         Kodiak_
  511.         Saeger
  512.         anixter
  513.         Hasty
  514.  
  515.         and everyone else I forgot...
  516.