diff --git a/doc/notes/ReleaseNotes b/doc/notes/ReleaseNotes index 1dd4de16..39d31c49 100644 --- a/doc/notes/ReleaseNotes +++ b/doc/notes/ReleaseNotes @@ -2425,3 +2425,7 @@ Put cap on maximum ambient gradient to avoid over-extrapolation of poorly computed irradiance cache values. Added robjutil +T option to triangulate all faces in .OBJ description. + +Altered BSDF library to have both front and back diffuse transmittance +values, which can be different. This was necessary to avoid issues +caused by measurement and modeling discrepancies. diff --git a/src/common/bsdf.c b/src/common/bsdf.c index af808753..e5572fc9 100644 --- a/src/common/bsdf.c +++ b/src/common/bsdf.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdf.c,v 2.58 2020/05/14 19:20:13 greg Exp $"; +static const char RCSid[] = "$Id: bsdf.c,v 2.59 2021/03/27 17:50:18 greg Exp $"; #endif /* * bsdf.c @@ -381,8 +381,10 @@ SDfreeBSDF(SDData *sd) sd->rLambFront.spec.flags = 0; sd->rLambBack.cieY = .0; sd->rLambBack.spec.flags = 0; - sd->tLamb.cieY = .0; - sd->tLamb.spec.flags = 0; + sd->tLambFront.cieY = .0; + sd->tLambFront.spec.flags = 0; + sd->tLambBack.cieY = .0; + sd->tLambBack.spec.flags = 0; } /* Find writeable BSDF by name, or allocate new cache entry if absent */ @@ -649,10 +651,10 @@ SDevalBSDF(SDValue *sv, const FVECT outVec, const FVECT inVec, const SDData *sd) *sv = sd->rLambBack; sdf = sd->rb; } else if (inFront) { - *sv = sd->tLamb; + *sv = sd->tLambFront; sdf = (sd->tf != NULL) ? sd->tf : sd->tb; } else /* outFront & !inFront */ { - *sv = sd->tLamb; + *sv = sd->tLambBack; sdf = (sd->tb != NULL) ? sd->tb : sd->tf; } sv->cieY *= 1./M_PI; @@ -695,7 +697,8 @@ SDdirectHemi(const FVECT inVec, int sflags, const SDData *sd) if ((sflags & SDsampDf+SDsampR) != SDsampDf+SDsampR) hsum = .0; if ((sflags & SDsampDf+SDsampT) == SDsampDf+SDsampT) - hsum += sd->tLamb.cieY; + hsum += (inVec[2] > 0) ? + sd->tLambFront.cieY : sd->tLambBack.cieY; /* gather non-diffuse components */ i = (((sflags & SDsampSp+SDsampR) == SDsampSp+SDsampR) & (rdf != NULL)) ? rdf->ncomp : 0; @@ -748,7 +751,7 @@ SDsampBSDF(SDValue *sv, FVECT ioVec, double randX, int sflags, const SDData *sd) sv->cieY = .0; rdiff = sv->cieY; if ((sflags & SDsampDf+SDsampT) == SDsampDf+SDsampT) - sv->cieY += sd->tLamb.cieY; + sv->cieY += inFront ? sd->tLambFront.cieY : sd->tLambBack.cieY; /* gather non-diffuse components */ i = nr = (((sflags & SDsampSp+SDsampR) == SDsampSp+SDsampR) & (rdf != NULL)) ? rdf->ncomp : 0; @@ -784,12 +787,13 @@ SDsampBSDF(SDValue *sv, FVECT ioVec, double randX, int sflags, const SDData *sd) randX -= rdiff; /* diffuse transmission? */ if ((sflags & SDsampDf+SDsampT) == SDsampDf+SDsampT) { - if (randX < sd->tLamb.cieY) { - sv->spec = sd->tLamb.spec; - SDdiffuseSamp(ioVec, !inFront, randX/sd->tLamb.cieY); + const SDValue *sdt = inFront ? &sd->tLambFront : &sd->tLambBack; + if (randX < sdt->cieY) { + sv->spec = sdt->spec; + SDdiffuseSamp(ioVec, !inFront, randX/sdt->cieY); goto done; } - randX -= sd->tLamb.cieY; + randX -= sdt->cieY; } /* else one of cumulative dist. */ for (i = 0; i < n && randX >= cdarr[i]->cTotal; i++) diff --git a/src/common/bsdf.h b/src/common/bsdf.h index 23f6fccb..5ccac34c 100644 --- a/src/common/bsdf.h +++ b/src/common/bsdf.h @@ -1,4 +1,4 @@ -/* RCSid $Id: bsdf.h,v 2.27 2020/05/14 19:20:13 greg Exp $ */ +/* RCSid $Id: bsdf.h,v 2.28 2021/03/27 17:50:18 greg Exp $ */ /* * bsdf.h * @@ -126,7 +126,8 @@ typedef struct { double dim[3]; /* width, height, thickness (meters) */ SDValue rLambFront; /* diffuse front reflectance */ SDValue rLambBack; /* diffuse rear reflectance */ - SDValue tLamb; /* diffuse transmission */ + SDValue tLambFront; /* diffuse front transmittance */ + SDValue tLambBack; /* diffuse back transmittance */ SDSpectralDF *rf, *rb; /* non-diffuse BRDF components */ SDSpectralDF *tf, *tb; /* non-diffuse BTDF components */ } SDData; diff --git a/src/common/bsdf_m.c b/src/common/bsdf_m.c index 38e3c907..28f1a95b 100644 --- a/src/common/bsdf_m.c +++ b/src/common/bsdf_m.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdf_m.c,v 3.40 2021/03/27 16:40:46 greg Exp $"; +static const char RCSid[] = "$Id: bsdf_m.c,v 3.41 2021/03/27 17:50:18 greg Exp $"; #endif /* * bsdf_m.c @@ -709,10 +709,8 @@ SDloadMtx(SDData *sd, ezxml_t wtl) /* separate diffuse components */ sd->rf = extract_diffuse(&sd->rLambFront, sd->rf); sd->rb = extract_diffuse(&sd->rLambBack, sd->rb); - if (sd->tb != NULL) - sd->tb = extract_diffuse(&sd->tLamb, sd->tb); - if (sd->tf != NULL) - sd->tf = extract_diffuse(&sd->tLamb, sd->tf); + sd->tf = extract_diffuse(&sd->tLambFront, sd->tf); + sd->tb = extract_diffuse(&sd->tLambBack, sd->tb); /* return success */ return SDEnone; } diff --git a/src/common/bsdf_t.c b/src/common/bsdf_t.c index 4deb60b5..5a8cbb6e 100644 --- a/src/common/bsdf_t.c +++ b/src/common/bsdf_t.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdf_t.c,v 3.49 2021/03/27 15:53:01 greg Exp $"; +static const char RCSid[] = "$Id: bsdf_t.c,v 3.50 2021/03/27 17:50:18 greg Exp $"; #endif /* * bsdf_t.c @@ -1430,10 +1430,8 @@ SDloadTre(SDData *sd, ezxml_t wtl) /* separate diffuse components */ extract_diffuse(&sd->rLambFront, sd->rf); extract_diffuse(&sd->rLambBack, sd->rb); - if (sd->tb != NULL) - extract_diffuse(&sd->tLamb, sd->tb); - if (sd->tf != NULL) - extract_diffuse(&sd->tLamb, sd->tf); + extract_diffuse(&sd->tLambFront, sd->tf); + extract_diffuse(&sd->tLambBack, sd->tb); /* return success */ return SDEnone; } diff --git a/src/common/loadbsdf.c b/src/common/loadbsdf.c index c3c6a58c..1a1c3e12 100644 --- a/src/common/loadbsdf.c +++ b/src/common/loadbsdf.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: loadbsdf.c,v 3.12 2020/05/14 19:20:13 greg Exp $"; +static const char RCSid[] = "$Id: loadbsdf.c,v 3.13 2021/03/27 17:50:18 greg Exp $"; #endif /* * Simple interface for loading BSDF, Radiance-specific search @@ -58,8 +58,8 @@ loadBSDF(char *fname) /* simple checks */ checkDF(sd->name, sd->rLambFront.cieY, sd->rf, "front reflection"); checkDF(sd->name, sd->rLambBack.cieY, sd->rb, "rear reflection"); - checkDF(sd->name, sd->tLamb.cieY, sd->tf, "front transmission"); - checkDF(sd->name, sd->tLamb.cieY, sd->tb, "back transmission"); + checkDF(sd->name, sd->tLambFront.cieY, sd->tf, "front transmission"); + checkDF(sd->name, sd->tLambBack.cieY, sd->tb, "back transmission"); #ifdef DEBUG { float rgb[3]; @@ -68,8 +68,10 @@ ccy2rgb(&sd->rLambFront.spec, sd->rLambFront.cieY, rgb); fprintf(stderr, "Front diffuse RGB: %.4f %.4f %.4f\n", rgb[0], rgb[1], rgb[2]); ccy2rgb(&sd->rLambBack.spec, sd->rLambBack.cieY, rgb); fprintf(stderr, "Back diffuse RGB: %.4f %.4f %.4f\n", rgb[0], rgb[1], rgb[2]); -ccy2rgb(&sd->tLamb.spec, sd->tLamb.cieY, rgb); -fprintf(stderr, "Diffuse RGB transmittance: %.4f %.4f %.4f\n", rgb[0], rgb[1], rgb[2]); +ccy2rgb(&sd->tLambFront.spec, sd->tLamb.cieY, rgb); +fprintf(stderr, "Front diffuse RGB transmittance: %.4f %.4f %.4f\n", rgb[0], rgb[1], rgb[2]); +ccy2rgb(&sd->tLambBack.spec, sd->tLamb.cieY, rgb); +fprintf(stderr, "Back diffuse RGB transmittance: %.4f %.4f %.4f\n", rgb[0], rgb[1], rgb[2]); if (sd->rf) fprintf(stderr, "Maximum direct hemispherical front reflection: %.3f%%\n", sd->rf->maxHemi*100.); diff --git a/src/common/testBSDF.c b/src/common/testBSDF.c index 5dfe197a..b854eba2 100644 --- a/src/common/testBSDF.c +++ b/src/common/testBSDF.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: testBSDF.c,v 1.15 2019/12/28 18:05:14 greg Exp $"; +static const char RCSid[] = "$Id: testBSDF.c,v 1.16 2021/03/27 17:50:18 greg Exp $"; #endif /* * Simple test program to demonstrate BSDF operation. @@ -126,13 +126,14 @@ main(int argc, char *argv[]) bsdf->rb->maxHemi); if (bsdf->tf) printf("Peak front hemispherical transmittance: %.3e\n", - bsdf->tLamb.cieY + bsdf->tf->maxHemi); + bsdf->tLambFront.cieY + bsdf->tf->maxHemi); if (bsdf->tb) printf("Peak back hemispherical transmittance: %.3e\n", - bsdf->tLamb.cieY + bsdf->tb->maxHemi); + bsdf->tLambBack.cieY + bsdf->tb->maxHemi); printXYZ("Diffuse Front Reflectance: ", &bsdf->rLambFront); printXYZ("Diffuse Back Reflectance: ", &bsdf->rLambBack); - printXYZ("Diffuse Transmittance: ", &bsdf->tLamb); + printXYZ("Diffuse Front Transmittance: ", &bsdf->tLambFront); + printXYZ("Diffuse Back Transmittance: ", &bsdf->tLambBack); break; case 'Q': /* query BSDF value */ if (!bsdf) diff --git a/src/cv/bsdf2klems.c b/src/cv/bsdf2klems.c index da331f28..4ee28690 100644 --- a/src/cv/bsdf2klems.c +++ b/src/cv/bsdf2klems.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdf2klems.c,v 2.32 2020/11/13 19:21:11 greg Exp $"; +static const char RCSid[] = "$Id: bsdf2klems.c,v 2.33 2021/03/27 17:50:18 greg Exp $"; #endif /* * Load measured BSDF interpolant and write out as XML file with Klems matrix. @@ -277,7 +277,7 @@ eval_bsdf(const char *fname) } } /* front transmission */ - if (bsd.tf != NULL || bsd.tLamb.cieY > .002) { + if (bsd.tf != NULL || bsd.tLambFront.cieY > .002) { input_orient = 1; output_orient = -1; cfp[CIE_Y] = open_component_file(CIE_Y); if (bsd.tf != NULL && bsd.tf->comp[0].cspec[2].flags) { diff --git a/src/cv/bsdf2rad.c b/src/cv/bsdf2rad.c index 8317b679..64e507a2 100644 --- a/src/cv/bsdf2rad.c +++ b/src/cv/bsdf2rad.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdf2rad.c,v 2.37 2021/02/12 00:53:56 greg Exp $"; +static const char RCSid[] = "$Id: bsdf2rad.c,v 2.38 2021/03/27 17:50:18 greg Exp $"; #endif /* * Plot 3-D BSDF output based on scattering interpolant or XML representation @@ -752,9 +752,10 @@ main(int argc, char *argv[]) overall_min = myBSDF.rLambFront.cieY/PI; if (back_comp & SDsampR && myBSDF.rLambBack.cieY < overall_min*PI) overall_min = myBSDF.rLambBack.cieY/PI; - if ((front_comp|back_comp) & SDsampT && - myBSDF.tLamb.cieY < overall_min*PI) - overall_min = myBSDF.tLamb.cieY/PI; + if (front_comp & SDsampT && myBSDF.tLambFront.cieY < overall_min*PI) + overall_min = myBSDF.tLambFront.cieY/PI; + if (back_comp & SDsampT && myBSDF.tLambBack.cieY < overall_min*PI) + overall_min = myBSDF.tLambBack.cieY/PI; } set_minlog(); if (!build_wBSDF(&myBSDF)) diff --git a/src/cv/bsdf2rado.c b/src/cv/bsdf2rado.c index c30475f1..8d0d1032 100644 --- a/src/cv/bsdf2rado.c +++ b/src/cv/bsdf2rado.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdf2rado.c,v 2.1 2018/06/07 15:39:36 greg Exp $"; +static const char RCSid[] = "$Id: bsdf2rado.c,v 2.2 2021/03/27 17:50:18 greg Exp $"; #endif /* * Plot 3-D BSDF output based on scattering interpolant or XML representation @@ -75,9 +75,10 @@ main(int argc, char *argv[]) bsdf_min = myBSDF.rLambFront.cieY/M_PI; if (myBSDF.rb != NULL && myBSDF.rLambBack.cieY < bsdf_min*M_PI) bsdf_min = myBSDF.rLambBack.cieY/M_PI; - if ((myBSDF.tf != NULL) | (myBSDF.tb != NULL) && - myBSDF.tLamb.cieY < bsdf_min*M_PI) - bsdf_min = myBSDF.tLamb.cieY/M_PI; + if (myBSDF.tf != NULL && myBSDF.tLambFront.cieY < bsdf_min*M_PI) + bsdf_min = myBSDF.tLambFront.cieY/M_PI; + if (myBSDF.tb != NULL && myBSDF.tLambBack.cieY < bsdf_min*M_PI) + bsdf_min = myBSDF.tLambBack.cieY/M_PI; if (doTrans && (myBSDF.tf == NULL) & (myBSDF.tb == NULL)) { fprintf(stderr, "%s: no transmitted component in '%s'\n", progname, argv[1]); diff --git a/src/rt/m_bsdf.c b/src/rt/m_bsdf.c index ed0fba01..b86370e2 100644 --- a/src/rt/m_bsdf.c +++ b/src/rt/m_bsdf.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: m_bsdf.c,v 2.61 2020/07/09 17:32:31 greg Exp $"; +static const char RCSid[] = "$Id: m_bsdf.c,v 2.62 2021/03/27 17:50:18 greg Exp $"; #endif /* * Shading for materials with BSDFs taken from XML data files @@ -195,7 +195,8 @@ compute_through(BSDFDAT *ndp) } if (vypeak*tomsurr < peak_over*bright(vsurr)*ns) return; /* peak not peaky enough */ - if ((vypeak/ns - ndp->sd->tLamb.cieY*(1./PI))*tomsum <= .001) + if ((vypeak/ns - (ndp->vray[2] > 0 ? ndp->sd->tLambFront.cieY + : ndp->sd->tLambBack.cieY)*(1./PI))*tomsum <= .001) return; /* < 0.1% transmission */ copycolor(ndp->cthru, vpeak); /* already scaled by omega */ multcolor(ndp->cthru, ndp->pr->pcol); /* modify by pattern */ @@ -255,10 +256,15 @@ direct_specular_OK(COLOR cval, FVECT ldir, double omega, BSDFDAT *ndp) return(0); /* all diffuse */ sv = ndp->sd->rLambBack; break; - default: + case 1: if ((ndp->sd->tf == NULL) & (ndp->sd->tb == NULL)) return(0); /* all diffuse */ - sv = ndp->sd->tLamb; + sv = ndp->sd->tLambFront; + break; + case 2: + if ((ndp->sd->tf == NULL) & (ndp->sd->tb == NULL)) + return(0); /* all diffuse */ + sv = ndp->sd->tLambBack; break; } if (sv.cieY > FTINY) { @@ -696,7 +702,7 @@ m_bsdf(OBJREC *m, RAY *r) } } /* diffuse transmittance */ - cvt_sdcolor(nd.tdiff, &nd.sd->tLamb); + cvt_sdcolor(nd.tdiff, hitfront ? &nd.sd->tLambFront : &nd.sd->tLambBack); if (m->oargs.nfargs >= 9) { setcolor(ctmp, m->oargs.farg[6], m->oargs.farg[7], diff --git a/src/util/cmbsdf.c b/src/util/cmbsdf.c index 82658bc5..20ec5849 100644 --- a/src/util/cmbsdf.c +++ b/src/util/cmbsdf.c @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: cmbsdf.c,v 2.9 2021/01/19 23:32:00 greg Exp $"; +static const char RCSid[] = "$Id: cmbsdf.c,v 2.10 2021/03/27 17:50:18 greg Exp $"; #endif /* * Load and convert BSDF into color coefficient matrix representation. @@ -157,8 +157,11 @@ cm_loadBTDF(const char *fname) ec = SDloadFile(&myBSDF, fname); if (ec) error(USER, transSDError(ec)); - ccy2rgb(&myBSDF.tLamb.spec, myBSDF.tLamb.cieY/PI, diffBTDF); recip = (myBSDF.tb == NULL); + if (recip) + ccy2rgb(&myBSDF.tLambFront.spec, myBSDF.tLambFront.cieY/PI, diffBTDF); + else + ccy2rgb(&myBSDF.tLambBack.spec, myBSDF.tLambBack.cieY/PI, diffBTDF); tdf = recip ? myBSDF.tf : myBSDF.tb; if (tdf == NULL) { /* no non-Lambertian transmission? */ SDfreeBSDF(&myBSDF);