--- ray/src/rt/m_wgmdf.c 2024/12/17 20:03:13 2.5 +++ ray/src/rt/m_wgmdf.c 2024/12/20 16:29:50 2.9 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: m_wgmdf.c,v 2.5 2024/12/17 20:03:13 greg Exp $"; +static const char RCSid[] = "$Id: m_wgmdf.c,v 2.9 2024/12/20 16:29:50 greg Exp $"; #endif /* * Shading function for programmable Ward-Geisler-Moroder-Duer material. @@ -158,23 +158,23 @@ fill_modval(MODVAL *mp, const WGMDDAT *wp) return(set_modval(mp, lastmod(objndx(wp->mtp), mp->nam), wp->rp)); } +/* set calculation context for given component of MAT_WGMDF */ static int setWGMDfunc(MODVAL *mp, const WGMDDAT *wp) { - static char lastMod[MAXSTR] = ""; + static char lastMod[MAXSTR]; double sf; FVECT vec; if (setfunc(wp->mtp, wp->rp) == 0 && !strcmp(mp->nam, lastMod)) return(0); /* already set */ - /* else (re)assign special variables */ strcpy(lastMod, mp->nam); - sf = (wp->rp->rod > 0) ? 1. : -1.; - varset("RdotP`", '=', (-1. < mp->pdot) & (mp->pdot < 1.) - ? sf*mp->pdot : 1.); - sf /= funcxf.sca; + /* else (re)assign special variables */ + sf = 1 - 2*(wp->rp->rod < 0); + varset("RdotP`", '=', mp->pdot*sf); multv3(vec, mp->pnorm, funcxf.xfm); + sf /= funcxf.sca; varset("NxP`", '=', vec[0]*sf); varset("NyP`", '=', vec[1]*sf); varset("NzP`", '=', vec[2]*sf); @@ -213,54 +213,45 @@ set_dcomp(WGMDDAT *wp, int trans) static void set_scomp(WGMDDAT *wp, int trans) { - SCOMP *sp = trans ? &wp->ts : &wp->rs; - const int eoff = 3*(trans != 0); - double coef; + SCOMP *sp = trans ? &wp->ts : &wp->rs; + EPNODE **exa = wp->mf->ep + 3*(trans != 0); + double coef; /* constant zero check */ - if (wp->mf->ep[eoff]->type == NUM && - wp->mf->ep[eoff]->v.num <= FTINY) { - scolorblack(sp->scol); - return; - } /* need modifier */ + if (exa[0]->type == NUM && exa[0]->v.num <= FTINY) + goto blackout; + /* need modifier */ sp->mo.nam = wp->mtp->oargs.sarg[4*(trans != 0)]; if (!fill_modval(&sp->mo, wp)) { sprintf(errmsg, "unknown specular %s modifier '%s'", trans ? "transmission" : "reflection", sp->mo.nam); objerror(wp->mtp, USER, errmsg); } - setWGMDfunc(&sp->mo, wp); + if (sintens(sp->mo.pcol) <= FTINY) + goto blackout; /* got black pattern */ + setWGMDfunc(&sp->mo, wp); /* else compute coefficient */ errno = 0; - coef = evalue(wp->mf->ep[eoff]); + coef = evalue(exa[0]); if ((errno == EDOM) | (errno == ERANGE)) { objerror(wp->mtp, WARNING, "specular compute error"); - scolorblack(sp->scol); - return; + goto blackout; } - if (coef <= FTINY) { /* negligible value? */ - scolorblack(sp->scol); - return; - } + if (coef <= FTINY) /* negligible value? */ + goto blackout; copyscolor(sp->scol, sp->mo.pcol); scalescolor(sp->scol, coef); - if (sintens(sp->scol) <= FTINY) { - scolorblack(sp->scol); - return; /* got black pattern */ - } errno = 0; /* else get roughness */ - sp->u_alpha = evalue(wp->mf->ep[eoff+1]); - sp->v_alpha = (sp->u_alpha > FTINY) ? evalue(wp->mf->ep[eoff+2]) : 0.0; + sp->u_alpha = evalue(exa[1]); + sp->v_alpha = (sp->u_alpha > FTINY) ? evalue(exa[2]) : 0.0; if ((errno == EDOM) | (errno == ERANGE)) { objerror(wp->mtp, WARNING, "roughness compute error"); - scolorblack(sp->scol); - return; + goto blackout; } /* we have something... */ wp->specfl |= trans ? SP_TRAN : SP_REFL; if (sp->v_alpha <= FTINY) { /* is it pure specular? */ wp->specfl |= trans ? SP_TPURE : SP_RPURE; sp->u_alpha = sp->v_alpha = 0.0; return; - } - /* get anisotropic coordinates */ + } /* else get aniso coordinates */ fcross(sp->v, sp->mo.pnorm, wp->ulocal); if (normalize(sp->v) == 0.0) { /* orientation vector==normal? */ if (fabs(sp->u_alpha - sp->v_alpha) > 0.001) @@ -271,6 +262,9 @@ set_scomp(WGMDDAT *wp, int trans) (sp->u_alpha*sp->u_alpha + sp->v_alpha*sp->v_alpha) ); } else fcross(sp->u, sp->v, sp->mo.pnorm); + return; +blackout: + scolorblack(sp->scol); /* zero out component */ } /* sample anisotropic Gaussian specular */ @@ -458,7 +452,7 @@ dirwgmdf(SCOLOR scval, void *uwp, FVECT ldir, double o */ /* add source width if flat */ if (wp->specfl & SP_FLAT) - au2 = av2 = omega * (0.25/PI); + au2 = av2 = (1. - dstrsrc) * omega * (0.25/PI); else au2 = av2 = 0.0; au2 += wp->rs.u_alpha*wp->rs.u_alpha; @@ -559,7 +553,8 @@ m_wgmdf(OBJREC *m, RAY *r) return(1); /* second shadow test */ set_dcomp(&wd, 1); set_scomp(&wd, 0); - wd.specfl |= SP_FLAT*(r->ro != NULL && isflat(r->ro->otype)); + wd.specfl |= SP_FLAT*(!wd.rs.mo.hastexture && + r->ro != NULL && isflat(r->ro->otype)); /* apply Fresnel adjustments? */ if (wd.specfl & SP_RPURE && pbright(wd.rs.scol) >= FRESTHRESH) { const double fest = FRESNE(fabs(wd.rs.mo.pdot)); @@ -618,8 +613,7 @@ m_wgmdf(OBJREC *m, RAY *r) copyscolor(r->mcol, lr.rcol); saddscolor(r->rcol, lr.rcol); r->rmt = r->rot; - if (wd.specfl & SP_FLAT && - !wd.rs.mo.hastexture | (r->crtype & AMBIENT)) + if (wd.specfl & SP_FLAT && r->crtype & AMBIENT) r->rmt += raydistance(&lr); } if (wd.specfl & (SP_REFL|SP_TRAN)) /* specularly scattered rays */