home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsiii / zdepth.c < prev   
Encoding:
C/C++ Source or Header  |  1992-12-14  |  3.7 KB  |  134 lines

  1. /*
  2.  *    Name (person to blame): Andrew Woo
  3.  *    Gem: Article 7.1, "The Shadow Depth Map Revisited"
  4.  *    Affiliation: Alias Research, Style! Division
  5.  */
  6. #include    <math.h>
  7.  
  8.  
  9. /***********************************************
  10.  Reeves' SampleShadow code using BIAS
  11. ************************************************/
  12.  
  13. #define REEVES_APPROACH {                                                    \
  14.     inshadow = 0;                                                            \
  15.     for (i = 0, s = smin; i < ns; i++, s += ds) {                            \
  16.         for (j = 0, t = tmin; j < nt; j++, t += dt) {                        \
  17.             iu = s + Rand()*js;                      /* jitter s, t */        \
  18.             iv = t + Rand()*jt;                                                \
  19.                                                                             \
  20.             bias = Rand() * (Bias1 - Bias0) + Bias0; /* pick bias */        \
  21.             if (iu >= bbox->r_umin && iu <= bbox->r_umax &&                 \
  22.                 iv >= bbox->r_vmin && iv <= bbox->r_vmax)                    \
  23.                 if (z > depthMap[iu][iv] + bias) inshadow++;                \
  24.         }                                                                    \
  25.     }                                                                        \
  26. }
  27.  
  28.  
  29.  
  30. /***********************************************
  31.  New SampleShadow code with no BIAS and doing
  32.  integer comparisons for depth values first.
  33. ************************************************/
  34.  
  35. #define NEW_APPROACH {                                                        \
  36.     register int integerZ = (int) z, intDepth;                                \
  37.     register float depthValue;                                                \
  38.     inshadow = 0;                                                            \
  39.                                                                             \
  40.     for (i = 0, s = smin; i < ns; i++, s += ds) {                            \
  41.         for (j = 0, t = tmin; j < nt; j++, t += dt) {                        \
  42.             iu = s + Rand()*js;                                                \
  43.             iv = t + Rand()*jt;                                                \
  44.             if (iu >= bbox->r_umin && iu <= bbox->r_umax &&                 \
  45.                 iv >= bbox->r_vmin && iv <= bbox->r_vmax) {                    \
  46.                 /* do integer comparison first */                            \
  47.                 depthValue = depthMap[iu][iv];                                \
  48.                 intDepth = (int) depthValue;                                \
  49.                 if ((integerZ > intDepth) ||                                 \
  50.                     (integerZ == intDepth && z > depthValue))                \
  51.                     inshadow++;                                                \
  52.             } else {                                                        \
  53.                 /* boundary case error */                                    \
  54.                 inshadow++;                                                    \
  55.             }                                                                \
  56.         }                                                                    \
  57.     }                                                                        \
  58. }
  59.  
  60.  
  61.  
  62. /* Start of Reeves' code in Siggraph 87 paper */
  63.  
  64. float ResFactor = 3;
  65. float MinSize = 0;
  66. float Bias0 = 0.3;
  67. float Bias1 = 0.4;
  68. int NumSamples = 16;
  69. int MinSamples = 1;
  70.  
  71. #define MAPRES                 256        /* I tested the code at 256x256 */
  72. float depthMap[MAPRES][MAPRES];
  73.  
  74. #define CLAMP(a,min,max)    (a<min?min:(a>max?max:a))
  75. float Rand();
  76.  
  77. typedef struct {
  78.     int r_umin, r_umax;
  79.     int r_vmin, r_vmax;
  80. } TextureRect;
  81.  
  82.  
  83. float SampleShadow (s, t, z, sres, tres, bbox)
  84. float s, t, z, sres, tres;
  85. TextureRect *bbox;
  86. {
  87.     int i, j, inshadow, iu, iv, ns, nt, lu, hu, lv, hv;
  88.     float smin, tmin, ds, dt, js, jt;
  89.     
  90.     /* convert to coordinates of depth map */
  91.     sres = MAPRES * sres * ResFactor;
  92.     tres = MAPRES * tres * ResFactor;
  93.     if (sres < MinSize) sres = MinSize;
  94.     if (tres < MinSize) tres = MinSize;
  95.     s *= MAPRES; t *= MAPRES;
  96.     
  97.     /* cull if outside bounding box */
  98.     lu = floor (s-sres); hu = ceil (s+sres);
  99.     lv = floor (t-tres); hv = ceil (t+tres);
  100.     if (lu > bbox->r_umax || hu < bbox->r_umin ||
  101.         lv > bbox->r_vmax || hv < bbox->r_vmin) 
  102.         return (1.0);    /* error in Reeves' code at boundary cases */
  103.         
  104.     /* calculate number of samples */
  105.     if (sres*tres*4 < NumSamples) {
  106.         ns = sres + sres + 0.5;
  107.         ns = CLAMP(ns, MinSamples, NumSamples);
  108.         nt = tres + tres + 0.5;
  109.         nt = CLAMP(nt, MinSamples, NumSamples);
  110.     }
  111.     else {
  112.         nt = sqrt(tres*NumSamples/sres) + 0.5;
  113.         nt = CLAMP(nt, MinSamples, NumSamples);
  114.         ns = ((float)NumSamples)/nt + 0.5;
  115.         ns = CLAMP(ns, MinSamples, NumSamples);
  116.     }
  117.     
  118.     /* setup jitter variables */
  119.     ds = 2*sres/ns; dt = 2*tres/nt;
  120.     js = ds*.5; jt = dt*.5;
  121.     smin = s - sres + js; tmin = t - tres + jt;
  122.     
  123.     /* decide which version you want... */
  124. #ifdef OLD_WAY
  125.     REEVES_APPROACH;
  126. #else
  127.     NEW_APPROACH;
  128. #endif
  129.  
  130.     return (((float) inshadow) / (ns*nt));
  131. }
  132.  
  133.  
  134.