--- ray/src/rt/normal.c 1992/05/16 08:37:06 2.19 +++ ray/src/rt/normal.c 1993/02/12 10:41:02 2.23 @@ -24,10 +24,8 @@ extern double specthresh; /* specular sampling thres extern double specjitter; /* specular sampling jitter */ /* - * This routine uses portions of the reflection - * model described by Cook and Torrance. - * The computation of specular components has been simplified by - * numerous approximations and ommisions to improve speed. + * This routine implements the isotropic Gaussian + * model described by Ward in Siggraph `92 article. * We orient the surface towards the incoming ray, so a single * surface can be used to represent an infinitely thin object. * @@ -104,12 +102,13 @@ double omega; /* light source size */ /* + source if flat */ if (np->specfl & SP_FLAT) dtmp += omega/(4.0*PI); - /* delta */ + /* half vector */ vtmp[0] = ldir[0] - np->rp->rdir[0]; vtmp[1] = ldir[1] - np->rp->rdir[1]; vtmp[2] = ldir[2] - np->rp->rdir[2]; d2 = DOT(vtmp, np->pnorm); - d2 = 2.0 - 2.0*d2/sqrt(DOT(vtmp,vtmp)); + d2 *= d2; + d2 = (DOT(vtmp,vtmp) - d2) / d2; /* gaussian */ dtmp = exp(-d2/dtmp)/(4.*PI*dtmp); /* worth using? */ @@ -137,7 +136,7 @@ double omega; /* light source size */ /* roughness + source */ dtmp = np->alpha2 + omega/PI; /* gaussian */ - dtmp = exp((2.*DOT(np->prdir,ldir)-2.)/dtmp)/(4.*PI*dtmp); + dtmp = exp((2.*DOT(np->prdir,ldir)-2.)/dtmp)/(PI*dtmp); /* worth using? */ if (dtmp > FTINY) { copycolor(ctmp, np->mcolor); @@ -369,7 +368,7 @@ register NORMDAT *np; if (rv[1] <= FTINY) d = 1.0; else - d = sqrt( np->alpha2/4.0 * -log(rv[1]) ); + d = sqrt( -log(rv[1]) * np->alpha2 ); for (i = 0; i < 3; i++) sr.rdir[i] = np->prdir[i] + d*(cosp*u[i] + sinp*v[i]); if (DOT(sr.rdir, r->ron) < -FTINY)