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