2 |
|
static const char RCSid[] = "$Id$"; |
3 |
|
#endif |
4 |
|
/* |
5 |
< |
================================================================== |
5 |
> |
|
6 |
> |
====================================================================== |
7 |
|
Photon map support routines for scattering by materials. |
8 |
|
|
9 |
|
Roland Schregle (roland.schregle@{hslu.ch, gmail.com}) |
10 |
|
(c) Fraunhofer Institute for Solar Energy Systems, |
11 |
+ |
supported by the German Research Foundation |
12 |
+ |
(DFG LU-204/10-2, "Fassadenintegrierte Regelsysteme FARESYS") |
13 |
|
(c) Lucerne University of Applied Sciences and Arts, |
14 |
< |
supported by the Swiss National Science Foundation (SNSF, #147053) |
15 |
< |
================================================================== |
14 |
> |
supported by the Swiss National Science Foundation |
15 |
> |
(SNSF #147053, "Daylight Redirecting Components") |
16 |
> |
====================================================================== |
17 |
|
|
18 |
|
*/ |
19 |
|
|
50 |
|
COLOR mcolor, scolor; |
51 |
|
FVECT vrefl, prdir, pnorm; |
52 |
|
double alpha2, rdiff, rspec, trans, tdiff, tspec, pdot; |
53 |
< |
} NORMDAT; |
53 |
> |
} NORMDAT; |
54 |
|
|
55 |
|
typedef struct { |
56 |
|
OBJREC *mp; |
59 |
|
COLOR mcolor, scolor; |
60 |
|
FVECT vrefl, prdir, u, v, pnorm; |
61 |
|
double u_alpha, v_alpha, rdiff, rspec, trans, tdiff, tspec, pdot; |
62 |
< |
} ANISODAT; |
62 |
> |
} ANISODAT; |
63 |
|
|
64 |
|
typedef struct { |
65 |
|
OBJREC *mp; |
73 |
|
double tspec; |
74 |
|
FVECT pnorm; |
75 |
|
double pdot; |
76 |
< |
} BRDFDAT; |
76 |
> |
} BRDFDAT; |
77 |
|
|
78 |
|
typedef struct { |
79 |
|
OBJREC *mp; |
149 |
|
} |
150 |
|
|
151 |
|
|
148 |
– |
|
152 |
|
static void addPhotons (const RAY *r) |
153 |
|
/* Insert photon hits, where applicable */ |
154 |
|
{ |
155 |
|
if (!r -> rlvl) |
156 |
< |
/* Add direct photon map at primary hitpoint */ |
156 |
> |
/* Add direct photon at primary hitpoint */ |
157 |
|
newPhoton(directPmap, r); |
158 |
|
else { |
159 |
< |
/* Add global or precomputed photon map at indirect hitpoint */ |
159 |
> |
/* Add global or precomputed photon at indirect hitpoint */ |
160 |
|
newPhoton(preCompPmap ? preCompPmap : globalPmap, r); |
161 |
|
|
162 |
|
/* Store caustic photon if specular flag set */ |
322 |
|
} |
323 |
|
else raytexture(rayIn, mat -> omod); |
324 |
|
|
325 |
+ |
nd.mp = mat; |
326 |
|
nd.rp = rayIn; |
327 |
|
|
328 |
|
/* Get material color */ |
484 |
|
|
485 |
|
|
486 |
|
|
487 |
< |
static void getacoords (ANISODAT *np) |
487 |
> |
static void getacoords (ANISODAT *nd) |
488 |
|
/* Set up coordinate system for anisotropic sampling; cloned from aniso.c */ |
489 |
|
{ |
490 |
< |
MFUNC *mf; |
491 |
< |
int i; |
490 |
> |
MFUNC *mf; |
491 |
> |
int i; |
492 |
|
|
493 |
< |
mf = getfunc(np->mp, 3, 0x7, 1); |
494 |
< |
setfunc(np->mp, np->rp); |
493 |
> |
mf = getfunc(nd -> mp, 3, 0x7, 1); |
494 |
> |
setfunc(nd -> mp, nd -> rp); |
495 |
|
errno = 0; |
496 |
|
|
497 |
|
for (i = 0; i < 3; i++) |
498 |
< |
np->u[i] = evalue(mf->ep[i]); |
498 |
> |
nd -> u [i] = evalue(mf -> ep [i]); |
499 |
|
|
500 |
< |
if ((errno == EDOM) | (errno == ERANGE)) { |
501 |
< |
objerror(np->mp, WARNING, "compute error"); |
498 |
< |
np->specfl |= SP_BADU; |
499 |
< |
return; |
500 |
< |
} |
501 |
< |
|
502 |
< |
if (mf->fxp != &unitxf) |
503 |
< |
multv3(np->u, np->u, mf->fxp->xfm); |
500 |
> |
if (errno == EDOM || errno == ERANGE) |
501 |
> |
nd -> u [0] = nd -> u [1] = nd -> u [2] = 0.0; |
502 |
|
|
503 |
< |
fcross(np->v, np->pnorm, np->u); |
503 |
> |
if (mf -> fxp != &unitxf) |
504 |
> |
multv3(nd -> u, nd -> u, mf -> fxp -> xfm); |
505 |
|
|
506 |
< |
if (normalize(np->v) == 0.0) { |
508 |
< |
objerror(np->mp, WARNING, "illegal orientation vector"); |
509 |
< |
np->specfl |= SP_BADU; |
510 |
< |
return; |
511 |
< |
} |
506 |
> |
fcross(nd -> v, nd -> pnorm, nd -> u); |
507 |
|
|
508 |
< |
fcross(np->u, np->v, np->pnorm); |
508 |
> |
if (normalize(nd -> v) == 0.0) { |
509 |
> |
if (fabs(nd -> u_alpha - nd -> v_alpha) > 0.001) |
510 |
> |
objerror(nd -> mp, WARNING, "illegal orientation vector"); |
511 |
> |
getperpendicular(nd -> u, nd -> pnorm, 1); |
512 |
> |
fcross(nd -> v, nd -> pnorm, nd -> u); |
513 |
> |
nd -> u_alpha = nd -> v_alpha = |
514 |
> |
sqrt(0.5 * (sqr(nd -> u_alpha) + sqr(nd -> v_alpha))); |
515 |
> |
} |
516 |
> |
else fcross(nd -> u, nd -> v, nd -> pnorm); |
517 |
|
} |
518 |
|
|
519 |
|
|
619 |
|
if (mat -> oargs.nfargs != (mat -> otype == MAT_TRANS2 ? 8 : 6)) |
620 |
|
objerror(mat, USER, "bad number of real arguments"); |
621 |
|
|
622 |
+ |
nd.mp = mat; |
623 |
|
nd.rp = rayIn; |
620 |
– |
nd.mp = objptr(rayIn -> ro -> omod); |
624 |
|
|
625 |
|
/* get material color */ |
626 |
|
copycolor(nd.mcolor, mat -> oargs.farg); |
664 |
|
if (nd.rspec > FTINY) { |
665 |
|
nd.specfl |= SP_REFL; |
666 |
|
|
667 |
< |
/* comput e specular color */ |
667 |
> |
/* compute specular color */ |
668 |
|
if (mat -> otype == MAT_METAL2) |
669 |
|
copycolor(nd.scolor, nd.mcolor); |
670 |
|
else setcolor(nd.scolor, 1, 1, 1); |
1036 |
|
/* Replacement scattering routine */ |
1037 |
|
photonScatter [aliasRec.otype] (&aliasRec, rayIn); |
1038 |
|
|
1036 |
– |
#if 0 |
1039 |
|
/* Avoid potential memory leak? */ |
1040 |
|
if (aliasRec.os != aliasPtr -> os) { |
1041 |
< |
if (aliasObj -> os) |
1042 |
< |
free_os(aliasObj); |
1041 |
> |
if (aliasPtr -> os) |
1042 |
> |
free_os(aliasPtr); |
1043 |
|
aliasPtr -> os = aliasRec.os; |
1044 |
|
} |
1043 |
– |
#endif |
1045 |
|
|
1046 |
|
return 0; |
1047 |
|
} |
1476 |
|
|
1477 |
|
|
1478 |
|
|
1479 |
< |
static int brtdFuncPhotonScatter (OBJREC *mat, RAY *rayIn) |
1480 |
< |
/* Generate new photon ray for BRTDfunc material and recurse */ |
1479 |
> |
static int brdfPhotonScatter (OBJREC *mat, RAY *rayIn) |
1480 |
> |
/* Generate new photon ray for BRTDfunc material and recurse. Only ideal |
1481 |
> |
reflection and transmission are sampled for the specular componentent. */ |
1482 |
|
{ |
1483 |
|
int hitfront = 1, hastexture, i; |
1484 |
|
BRDFDAT nd; |
1488 |
|
MFUNC *mf; |
1489 |
|
FVECT bnorm; |
1490 |
|
|
1491 |
+ |
/* Check argz */ |
1492 |
|
if (mat -> oargs.nsargs < 10 || mat -> oargs.nfargs < 9) |
1493 |
|
objerror(mat, USER, "bad # arguments"); |
1494 |
+ |
|
1495 |
|
nd.mp = mat; |
1496 |
|
nd.pr = rayIn; |
1497 |
< |
/* Dummies */ |
1497 |
> |
/* Dummiez */ |
1498 |
|
nd.rspec = nd.tspec = 1.0; |
1499 |
|
nd.trans = 0.5; |
1500 |
|
|
1501 |
< |
/* Diffuse reflectance */ |
1501 |
> |
/* Diffuz reflektanz */ |
1502 |
|
if (rayIn -> rod > 0.0) |
1503 |
|
setcolor(nd.rdiff, mat -> oargs.farg[0], mat -> oargs.farg [1], |
1504 |
|
mat -> oargs.farg [2]); |
1505 |
|
else |
1506 |
|
setcolor(nd.rdiff, mat-> oargs.farg [3], mat -> oargs.farg [4], |
1507 |
|
mat -> oargs.farg [5]); |
1508 |
< |
/* Diffuse transmittance */ |
1508 |
> |
/* Diffuz tranzmittanz */ |
1509 |
|
setcolor(nd.tdiff, mat -> oargs.farg [6], mat -> oargs.farg [7], |
1510 |
|
mat -> oargs.farg [8]); |
1511 |
|
|
1512 |
< |
/* Get modifiers */ |
1512 |
> |
/* Get modz */ |
1513 |
|
raytexture(rayIn, mat -> omod); |
1514 |
|
hastexture = (DOT(rayIn -> pert, rayIn -> pert) > sqr(FTINY)); |
1515 |
|
if (hastexture) { |
1522 |
|
} |
1523 |
|
|
1524 |
|
if (rayIn -> rod < 0.0) { |
1525 |
< |
/* Orient perturbed values */ |
1525 |
> |
/* Orient perturbed valuz */ |
1526 |
|
nd.pdot = -nd.pdot; |
1527 |
|
for (i = 0; i < 3; i++) { |
1528 |
|
nd.pnorm [i] = -nd.pnorm [i]; |
1532 |
|
hitfront = 0; |
1533 |
|
} |
1534 |
|
|
1535 |
< |
/* Get pattern color, modify diffuse values */ |
1535 |
> |
/* Get pattern kolour, modify diffuz valuz */ |
1536 |
|
copycolor(nd.mcolor, rayIn -> pcol); |
1537 |
|
multcolor(nd.rdiff, nd.mcolor); |
1538 |
|
multcolor(nd.tdiff, nd.mcolor); |
1539 |
|
|
1540 |
< |
/* Load cal file, evaluate spec refl/trans vars */ |
1540 |
> |
/* Load cal file, evaluate spekula refl/tranz varz */ |
1541 |
|
nd.dp = NULL; |
1542 |
|
mf = getfunc(mat, 9, 0x3f, 0); |
1543 |
|
setbrdfunc(&nd); |
1549 |
|
if (errno == EDOM || errno == ERANGE) |
1550 |
|
objerror(mat, WARNING, "compute error"); |
1551 |
|
else { |
1552 |
< |
/* Set up probabilities */ |
1552 |
> |
/* Set up probz */ |
1553 |
|
prDiff = colorAvg(nd.rdiff); |
1554 |
|
ptDiff = colorAvg(nd.tdiff); |
1555 |
|
prSpec = colorAvg(rspecCol); |
1557 |
|
albedo = prDiff + ptDiff + prSpec + ptSpec; |
1558 |
|
} |
1559 |
|
|
1560 |
< |
/* Insert direct and indirect photon hits if diffuse component */ |
1560 |
> |
/* Insert direct and indirect photon hitz if diffuz komponent */ |
1561 |
|
if (prDiff > FTINY || ptDiff > FTINY) |
1562 |
|
addPhotons(rayIn); |
1563 |
|
|
1564 |
< |
/* Stochastically sample absorption or scattering events */ |
1564 |
> |
/* Stochastically sample absorption or scattering evenz */ |
1565 |
|
if ((xi = pmapRandom(rouletteState)) > albedo) |
1566 |
|
/* Absorbed */ |
1567 |
|
return 0; |
1568 |
|
|
1569 |
|
if (xi > (albedo -= prSpec)) { |
1570 |
< |
/* Specular reflection */ |
1570 |
> |
/* Ideal spekula reflekzion */ |
1571 |
|
photonRay(rayIn, &rayOut, PMAP_SPECREFL, rspecCol); |
1572 |
|
VSUM(rayOut.rdir, rayIn -> rdir, nd.pnorm, 2 * nd.pdot); |
1573 |
|
checknorm(rayOut.rdir); |
1574 |
|
} |
1575 |
|
else if (xi > (albedo -= ptSpec)) { |
1576 |
< |
/* Specular transmission */ |
1576 |
> |
/* Ideal spekula tranzmission */ |
1577 |
|
photonRay(rayIn, &rayOut, PMAP_SPECTRANS, tspecCol); |
1578 |
|
if (hastexture) { |
1579 |
< |
/* Perturb direction */ |
1579 |
> |
/* Perturb direkzion */ |
1580 |
|
VSUB(rayOut.rdir, rayIn -> rdir, rayIn -> pert); |
1581 |
|
if (normalize(rayOut.rdir) == 0.0) { |
1582 |
|
objerror(mat, WARNING, "illegal perturbation"); |
1583 |
|
VCOPY(rayOut.rdir, rayIn -> rdir); |
1584 |
|
} |
1581 |
– |
else VCOPY(rayOut.rdir, rayIn -> rdir); |
1585 |
|
} |
1586 |
+ |
else VCOPY(rayOut.rdir, rayIn -> rdir); |
1587 |
|
} |
1588 |
|
else if (xi > (albedo -= prDiff)) { |
1589 |
< |
/* Diffuse reflection */ |
1589 |
> |
/* Diffuz reflekzion */ |
1590 |
|
if (!hitfront) |
1591 |
|
flipsurface(rayIn); |
1592 |
|
photonRay(rayIn, &rayOut, PMAP_DIFFREFL, nd.mcolor); |
1593 |
|
diffPhotonScatter(nd.pnorm, &rayOut); |
1594 |
|
} |
1595 |
|
else { |
1596 |
< |
/* Diffuse transmission */ |
1596 |
> |
/* Diffuz tranzmission */ |
1597 |
|
if (hitfront) |
1598 |
|
flipsurface(rayIn); |
1599 |
|
photonRay(rayIn, &rayOut, PMAP_DIFFTRANS, nd.mcolor); |
1603 |
|
diffPhotonScatter(bnorm, &rayOut); |
1604 |
|
} |
1605 |
|
|
1606 |
+ |
tracePhoton(&rayOut); |
1607 |
|
return 0; |
1608 |
|
} |
1609 |
|
|
1610 |
|
|
1611 |
|
|
1612 |
< |
#if 0 |
1613 |
< |
int |
1614 |
< |
m_brdf2( /* color a ray that hit a BRDF material */ |
1610 |
< |
OBJREC *m, |
1611 |
< |
RAY *r |
1612 |
< |
) |
1612 |
> |
int brdf2PhotonScatter (OBJREC *mat, RAY *rayIn) |
1613 |
> |
/* Generate new photon ray for procedural or data driven BRDF material and |
1614 |
> |
recurse. Only diffuse reflection and transmission are sampled. */ |
1615 |
|
{ |
1616 |
< |
BRDFDAT nd; |
1617 |
< |
COLOR ctmp; |
1618 |
< |
FVECT vtmp; |
1619 |
< |
double dtmp; |
1620 |
< |
/* always a shadow */ |
1619 |
< |
if (r->crtype & SHADOW) |
1620 |
< |
return(1); |
1621 |
< |
/* check arguments */ |
1622 |
< |
if ((m->oargs.nsargs < (hasdata(m->otype)?4:2)) | (m->oargs.nfargs < |
1623 |
< |
((m->otype==MAT_TFUNC)|(m->otype==MAT_TDATA)?6:4))) |
1624 |
< |
objerror(m, USER, "bad # arguments"); |
1625 |
< |
/* check for back side */ |
1626 |
< |
if (r->rod < 0.0) { |
1627 |
< |
if (!backvis) { |
1628 |
< |
raytrans(r); |
1629 |
< |
return(1); |
1630 |
< |
} |
1631 |
< |
raytexture(r, m->omod); |
1632 |
< |
flipsurface(r); /* reorient if backvis */ |
1633 |
< |
} else |
1634 |
< |
raytexture(r, m->omod); |
1616 |
> |
BRDFDAT nd; |
1617 |
> |
RAY rayOut; |
1618 |
> |
double dtmp, prDiff, ptDiff, albedo, xi; |
1619 |
> |
MFUNC *mf; |
1620 |
> |
FVECT bnorm; |
1621 |
|
|
1622 |
< |
nd.mp = m; |
1623 |
< |
nd.pr = r; |
1624 |
< |
/* get material color */ |
1625 |
< |
setcolor(nd.mcolor, m->oargs.farg[0], |
1626 |
< |
m->oargs.farg[1], |
1627 |
< |
m->oargs.farg[2]); |
1628 |
< |
/* get specular component */ |
1629 |
< |
nd.rspec = m->oargs.farg[3]; |
1630 |
< |
/* compute transmittance */ |
1631 |
< |
if ((m->otype == MAT_TFUNC) | (m->otype == MAT_TDATA)) { |
1632 |
< |
nd.trans = m->oargs.farg[4]*(1.0 - nd.rspec); |
1633 |
< |
nd.tspec = nd.trans * m->oargs.farg[5]; |
1634 |
< |
dtmp = nd.trans - nd.tspec; |
1635 |
< |
setcolor(nd.tdiff, dtmp, dtmp, dtmp); |
1636 |
< |
} else { |
1637 |
< |
nd.tspec = nd.trans = 0.0; |
1638 |
< |
setcolor(nd.tdiff, 0.0, 0.0, 0.0); |
1639 |
< |
} |
1654 |
< |
/* compute reflectance */ |
1655 |
< |
dtmp = 1.0 - nd.trans - nd.rspec; |
1656 |
< |
setcolor(nd.rdiff, dtmp, dtmp, dtmp); |
1657 |
< |
nd.pdot = raynormal(nd.pnorm, r); /* perturb normal */ |
1658 |
< |
multcolor(nd.mcolor, r->pcol); /* modify material color */ |
1659 |
< |
multcolor(nd.rdiff, nd.mcolor); |
1660 |
< |
multcolor(nd.tdiff, nd.mcolor); |
1661 |
< |
/* load auxiliary files */ |
1662 |
< |
if (hasdata(m->otype)) { |
1663 |
< |
nd.dp = getdata(m->oargs.sarg[1]); |
1664 |
< |
getfunc(m, 2, 0, 0); |
1665 |
< |
} else { |
1666 |
< |
nd.dp = NULL; |
1667 |
< |
getfunc(m, 1, 0, 0); |
1668 |
< |
} |
1669 |
< |
/* compute ambient */ |
1670 |
< |
if (nd.trans < 1.0-FTINY) { |
1671 |
< |
copycolor(ctmp, nd.mcolor); /* modified by material color */ |
1672 |
< |
scalecolor(ctmp, 1.0-nd.trans); |
1673 |
< |
multambient(ctmp, r, nd.pnorm); |
1674 |
< |
addcolor(r->rcol, ctmp); /* add to returned color */ |
1675 |
< |
} |
1676 |
< |
if (nd.trans > FTINY) { /* from other side */ |
1677 |
< |
flipsurface(r); |
1678 |
< |
vtmp[0] = -nd.pnorm[0]; |
1679 |
< |
vtmp[1] = -nd.pnorm[1]; |
1680 |
< |
vtmp[2] = -nd.pnorm[2]; |
1681 |
< |
copycolor(ctmp, nd.mcolor); |
1682 |
< |
scalecolor(ctmp, nd.trans); |
1683 |
< |
multambient(ctmp, r, vtmp); |
1684 |
< |
addcolor(r->rcol, ctmp); |
1685 |
< |
flipsurface(r); |
1686 |
< |
} |
1687 |
< |
/* add direct component */ |
1688 |
< |
direct(r, dirbrdf, &nd); |
1622 |
> |
/* Check argz */ |
1623 |
> |
if (mat -> oargs.nsargs < (hasdata(mat -> otype) ? 4 : 2) || |
1624 |
> |
mat -> oargs.nfargs < (mat -> otype == MAT_TFUNC || |
1625 |
> |
mat -> otype == MAT_TDATA ? 6 : 4)) |
1626 |
> |
objerror(mat, USER, "bad # arguments"); |
1627 |
> |
|
1628 |
> |
if (rayIn -> rod < 0.0) { |
1629 |
> |
/* Hit backside; reorient if visible, else transfer photon */ |
1630 |
> |
if (!backvis) { |
1631 |
> |
photonRay(rayIn, &rayOut, PMAP_XFER, NULL); |
1632 |
> |
tracePhoton(&rayOut); |
1633 |
> |
return 0; |
1634 |
> |
} |
1635 |
> |
|
1636 |
> |
raytexture(rayIn, mat -> omod); |
1637 |
> |
flipsurface(rayIn); |
1638 |
> |
} |
1639 |
> |
else raytexture(rayIn, mat -> omod); |
1640 |
|
|
1641 |
< |
return(1); |
1641 |
> |
nd.mp = mat; |
1642 |
> |
nd.pr = rayIn; |
1643 |
> |
|
1644 |
> |
/* Material kolour */ |
1645 |
> |
setcolor(nd.mcolor, mat -> oargs.farg [0], mat -> oargs.farg [1], |
1646 |
> |
mat -> oargs.farg [2]); |
1647 |
> |
/* Spekula komponent */ |
1648 |
> |
nd.rspec = mat -> oargs.farg [3]; |
1649 |
> |
|
1650 |
> |
/* Tranzmittanz */ |
1651 |
> |
if (mat -> otype == MAT_TFUNC || mat -> otype == MAT_TDATA) { |
1652 |
> |
nd.trans = mat -> oargs.farg [4] * (1.0 - nd.rspec); |
1653 |
> |
nd.tspec = nd.trans * mat -> oargs.farg [5]; |
1654 |
> |
dtmp = nd.trans - nd.tspec; |
1655 |
> |
setcolor(nd.tdiff, dtmp, dtmp, dtmp); |
1656 |
> |
} |
1657 |
> |
else { |
1658 |
> |
nd.tspec = nd.trans = 0.0; |
1659 |
> |
setcolor(nd.tdiff, 0.0, 0.0, 0.0); |
1660 |
> |
} |
1661 |
> |
|
1662 |
> |
/* Reflektanz */ |
1663 |
> |
dtmp = 1.0 - nd.trans - nd.rspec; |
1664 |
> |
setcolor(nd.rdiff, dtmp, dtmp, dtmp); |
1665 |
> |
/* Perturb normal */ |
1666 |
> |
nd.pdot = raynormal(nd.pnorm, rayIn); |
1667 |
> |
/* Modify material kolour */ |
1668 |
> |
multcolor(nd.mcolor, rayIn -> pcol); |
1669 |
> |
multcolor(nd.rdiff, nd.mcolor); |
1670 |
> |
multcolor(nd.tdiff, nd.mcolor); |
1671 |
> |
|
1672 |
> |
/* Load auxiliary filez */ |
1673 |
> |
if (hasdata(mat -> otype)) { |
1674 |
> |
nd.dp = getdata(mat -> oargs.sarg [1]); |
1675 |
> |
getfunc(mat, 2, 0, 0); |
1676 |
> |
} |
1677 |
> |
else { |
1678 |
> |
nd.dp = NULL; |
1679 |
> |
getfunc(mat, 1, 0, 0); |
1680 |
> |
} |
1681 |
> |
|
1682 |
> |
/* Set up probz */ |
1683 |
> |
prDiff = colorAvg(nd.rdiff); |
1684 |
> |
ptDiff = colorAvg(nd.tdiff); |
1685 |
> |
albedo = prDiff + ptDiff; |
1686 |
> |
|
1687 |
> |
/* Insert direct and indirect photon hitz if diffuz komponent */ |
1688 |
> |
if (prDiff > FTINY || ptDiff > FTINY) |
1689 |
> |
addPhotons(rayIn); |
1690 |
> |
|
1691 |
> |
/* Stochastically sample absorption or scattering evenz */ |
1692 |
> |
if ((xi = pmapRandom(rouletteState)) > albedo) |
1693 |
> |
/* Absorbed */ |
1694 |
> |
return 0; |
1695 |
> |
|
1696 |
> |
if (xi > (albedo -= prDiff)) { |
1697 |
> |
/* Diffuz reflekzion */ |
1698 |
> |
photonRay(rayIn, &rayOut, PMAP_DIFFREFL, nd.rdiff); |
1699 |
> |
diffPhotonScatter(nd.pnorm, &rayOut); |
1700 |
> |
} |
1701 |
> |
else { |
1702 |
> |
/* Diffuz tranzmission */ |
1703 |
> |
flipsurface(rayIn); |
1704 |
> |
photonRay(rayIn, &rayOut, PMAP_DIFFTRANS, nd.tdiff); |
1705 |
> |
bnorm [0] = -nd.pnorm [0]; |
1706 |
> |
bnorm [1] = -nd.pnorm [1]; |
1707 |
> |
bnorm [2] = -nd.pnorm [2]; |
1708 |
> |
diffPhotonScatter(bnorm, &rayOut); |
1709 |
> |
} |
1710 |
> |
|
1711 |
> |
tracePhoton(&rayOut); |
1712 |
> |
return 0; |
1713 |
|
} |
1692 |
– |
#endif |
1714 |
|
|
1715 |
|
|
1716 |
|
|
1717 |
|
/* |
1718 |
< |
================================================================== |
1718 |
> |
====================================================================== |
1719 |
|
The following code is |
1720 |
|
(c) Lucerne University of Applied Sciences and Arts, |
1721 |
< |
supported by the Swiss National Science Foundation (SNSF, #147053) |
1722 |
< |
================================================================== |
1721 |
> |
supported by the Swiss National Science Foundation |
1722 |
> |
(SNSF #147053, "Daylight Redirecting Components") |
1723 |
> |
====================================================================== |
1724 |
|
*/ |
1725 |
|
|
1726 |
|
static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn) |
1727 |
|
/* Generate new photon ray for BSDF modifier and recurse. */ |
1728 |
|
{ |
1729 |
< |
int hasthick = (mat->otype == MAT_BSDF); |
1730 |
< |
int hitFront; |
1731 |
< |
SDError err; |
1732 |
< |
SDValue bsdfVal; |
1733 |
< |
FVECT upvec; |
1734 |
< |
MFUNC *mf; |
1735 |
< |
BSDFDAT nd; |
1736 |
< |
RAY rayOut; |
1737 |
< |
COLOR bsdfRGB; |
1738 |
< |
int transmitted; |
1739 |
< |
double prDiff, ptDiff, prDiffSD, ptDiffSD, prSpecSD, ptSpecSD, |
1740 |
< |
albedo, xi; |
1741 |
< |
const double patAlb = bright(rayIn -> pcol); |
1729 |
> |
int hasthick = (mat->otype == MAT_BSDF); |
1730 |
> |
int hitFront; |
1731 |
> |
SDError err; |
1732 |
> |
SDValue bsdfVal; |
1733 |
> |
FVECT upvec; |
1734 |
> |
MFUNC *mf; |
1735 |
> |
BSDFDAT nd; |
1736 |
> |
RAY rayOut; |
1737 |
> |
COLOR bsdfRGB; |
1738 |
> |
int transmitted; |
1739 |
> |
double prDiff, ptDiff, prDiffSD, ptDiffSD, prSpecSD, ptSpecSD, |
1740 |
> |
albedo, xi; |
1741 |
> |
const double patAlb = bright(rayIn -> pcol); |
1742 |
|
|
1743 |
|
/* Following code adapted from m_bsdf() */ |
1744 |
|
/* Check arguments */ |
1745 |
< |
if (mat -> oargs.nsargs < hasthick+5 || mat -> oargs.nfargs > 9 || |
1746 |
< |
mat -> oargs.nfargs % 3) |
1745 |
> |
if ( |
1746 |
> |
mat -> oargs.nsargs < hasthick+5 || |
1747 |
> |
mat -> oargs.nfargs > 9 || mat -> oargs.nfargs % 3 |
1748 |
> |
) |
1749 |
|
objerror(mat, USER, "bad # arguments"); |
1750 |
|
|
1751 |
|
hitFront = (rayIn -> rod > 0); |
1756 |
|
/* Get thickness */ |
1757 |
|
nd.thick = 0; |
1758 |
|
if (hasthick) { |
1759 |
< |
nd.thick = evalue(mf -> ep [0]); |
1760 |
< |
if ((-FTINY <= nd.thick) & (nd.thick <= FTINY)) |
1761 |
< |
nd.thick = .0; |
1759 |
> |
nd.thick = evalue(mf -> ep [0]); |
1760 |
> |
if ((-FTINY <= nd.thick) & (nd.thick <= FTINY)) |
1761 |
> |
nd.thick = .0; |
1762 |
|
} |
1763 |
|
|
1764 |
|
/* Get BSDF data */ |
1768 |
|
if (hitFront) { |
1769 |
|
if (mat -> oargs.nfargs < 3) |
1770 |
|
setcolor(nd.rdiff, .0, .0, .0); |
1771 |
< |
else setcolor(nd.rdiff, mat -> oargs.farg [0], mat -> oargs.farg [1], |
1772 |
< |
mat -> oargs.farg [2]); |
1771 |
> |
else setcolor( |
1772 |
> |
nd.rdiff, |
1773 |
> |
mat -> oargs.farg [0], mat -> oargs.farg [1], mat -> oargs.farg [2] |
1774 |
> |
); |
1775 |
|
} |
1776 |
|
else if (mat -> oargs.nfargs < 6) { |
1777 |
|
/* Check for absorbing backside */ |
1782 |
|
|
1783 |
|
setcolor(nd.rdiff, .0, .0, .0); |
1784 |
|
} |
1785 |
< |
else setcolor(nd.rdiff, mat -> oargs.farg [3], mat -> oargs.farg [4], |
1786 |
< |
mat -> oargs.farg [5]); |
1785 |
> |
else setcolor( |
1786 |
> |
nd.rdiff, |
1787 |
> |
mat -> oargs.farg [3], mat -> oargs.farg [4], mat -> oargs.farg [5] |
1788 |
> |
); |
1789 |
|
|
1790 |
|
/* Extra diffuse transmittance from material def */ |
1791 |
|
if (mat -> oargs.nfargs < 9) |
1792 |
|
setcolor(nd.tdiff, .0, .0, .0); |
1793 |
< |
else setcolor(nd.tdiff, mat -> oargs.farg [6], mat -> oargs.farg [7], |
1794 |
< |
mat -> oargs.farg [8]); |
1793 |
> |
else setcolor( |
1794 |
> |
nd.tdiff, |
1795 |
> |
mat -> oargs.farg [6], mat -> oargs.farg [7], mat -> oargs.farg [8] |
1796 |
> |
); |
1797 |
|
|
1798 |
|
nd.mp = mat; |
1799 |
|
nd.pr = rayIn; |
1842 |
|
} |
1843 |
|
|
1844 |
|
/* Determine BSDF resolution */ |
1845 |
< |
err = SDsizeBSDF(nd.sr_vpsa, nd.vray, NULL, |
1846 |
< |
SDqueryMin + SDqueryMax, nd.sd); |
1845 |
> |
err = SDsizeBSDF( |
1846 |
> |
nd.sr_vpsa, nd.vray, NULL, SDqueryMin + SDqueryMax, nd.sd |
1847 |
> |
); |
1848 |
|
|
1849 |
|
if (err) |
1850 |
|
objerror(mat, USER, transSDError(err)); |
1905 |
|
else { /* Sample SDF */ |
1906 |
|
if ((xi -= prDiffSD) <= 0) { |
1907 |
|
/* Diffuse SDF reflection (constant component) */ |
1908 |
< |
if ((err = SDsampBSDF(&bsdfVal, nd.vray, pmapRandom(scatterState), |
1909 |
< |
SDsampDf | SDsampR, nd.sd))) |
1908 |
> |
if ((err = SDsampBSDF( |
1909 |
> |
&bsdfVal, nd.vray, pmapRandom(scatterState), |
1910 |
> |
SDsampDf | SDsampR, nd.sd |
1911 |
> |
))) |
1912 |
|
objerror(mat, USER, transSDError(err)); |
1913 |
|
|
1914 |
|
/* Apply pattern to spectral component */ |
1919 |
|
|
1920 |
|
else if ((xi -= ptDiffSD) <= 0) { |
1921 |
|
/* Diffuse SDF transmission (constant component) */ |
1922 |
< |
if ((err = SDsampBSDF(&bsdfVal, nd.vray, pmapRandom(scatterState), |
1923 |
< |
SDsampDf | SDsampT, nd.sd))) |
1922 |
> |
if ((err = SDsampBSDF( |
1923 |
> |
&bsdfVal, nd.vray, pmapRandom(scatterState), |
1924 |
> |
SDsampDf | SDsampT, nd.sd |
1925 |
> |
))) |
1926 |
|
objerror(mat, USER, transSDError(err)); |
1927 |
|
|
1928 |
|
/* Apply pattern to spectral component */ |
1935 |
|
|
1936 |
|
else if ((xi -= prSpecSD) <= 0) { |
1937 |
|
/* Non-diffuse ("specular") SDF reflection */ |
1938 |
< |
if ((err = SDsampBSDF(&bsdfVal, nd.vray, pmapRandom(scatterState), |
1939 |
< |
SDsampSp | SDsampR, nd.sd))) |
1938 |
> |
if ((err = SDsampBSDF( |
1939 |
> |
&bsdfVal, nd.vray, pmapRandom(scatterState), |
1940 |
> |
SDsampSp | SDsampR, nd.sd |
1941 |
> |
))) |
1942 |
|
objerror(mat, USER, transSDError(err)); |
1943 |
|
|
1944 |
|
ccy2rgb(&bsdfVal.spec, bsdfVal.cieY, bsdfRGB); |
1947 |
|
|
1948 |
|
else { |
1949 |
|
/* Non-diffuse ("specular") SDF transmission */ |
1950 |
< |
if ((err = SDsampBSDF(&bsdfVal, nd.vray, pmapRandom(scatterState), |
1951 |
< |
SDsampSp | SDsampT, nd.sd))) |
1950 |
> |
if ((err = SDsampBSDF( |
1951 |
> |
&bsdfVal, nd.vray, pmapRandom(scatterState), |
1952 |
> |
SDsampSp | SDsampT, nd.sd |
1953 |
> |
))) |
1954 |
|
objerror(mat, USER, transSDError(err)); |
1955 |
|
|
1956 |
|
/* Apply pattern to spectral component */ |
1992 |
|
/* Init photonScatter[] dispatch table */ |
1993 |
|
{ |
1994 |
|
int i; |
1995 |
< |
|
1995 |
> |
|
1996 |
|
/* Catch-all for inconsistencies */ |
1997 |
|
for (i = 0; i < NUMOTYPE; i++) |
1998 |
|
photonScatter [i] = o_default; |
1999 |
< |
|
1999 |
> |
|
2000 |
|
photonScatter [MAT_LIGHT] = photonScatter [MAT_ILLUM] = |
2001 |
|
photonScatter [MAT_GLOW] = photonScatter [MAT_SPOT] = |
2002 |
|
lightPhotonScatter; |
2003 |
< |
|
2003 |
> |
|
2004 |
|
photonScatter [MAT_PLASTIC] = photonScatter [MAT_METAL] = |
2005 |
|
photonScatter [MAT_TRANS] = normalPhotonScatter; |
2006 |
|
|
2009 |
|
|
2010 |
|
photonScatter [MAT_DIELECTRIC] = photonScatter [MAT_INTERFACE] = |
2011 |
|
dielectricPhotonScatter; |
2012 |
< |
|
2012 |
> |
|
2013 |
|
photonScatter [MAT_MIST] = mistPhotonScatter; |
2014 |
|
photonScatter [MAT_GLASS] = glassPhotonScatter; |
2015 |
|
photonScatter [MAT_CLIP] = clipPhotonScatter; |
2017 |
|
photonScatter [MIX_FUNC] = mx_funcPhotonScatter; |
2018 |
|
photonScatter [MIX_DATA] = mx_dataPhotonScatter; |
2019 |
|
photonScatter [MIX_PICT]= mx_pdataPhotonScatter; |
2020 |
< |
|
2020 |
> |
|
2021 |
|
photonScatter [PAT_BDATA] = photonScatter [PAT_CDATA] = |
2022 |
|
photonScatter [PAT_BFUNC] = photonScatter [PAT_CFUNC] = |
2023 |
|
photonScatter [PAT_CPICT] = photonScatter [TEX_FUNC] = |
2024 |
|
photonScatter [TEX_DATA] = pattexPhotonScatter; |
2025 |
< |
|
2025 |
> |
|
2026 |
|
photonScatter [MOD_ALIAS] = aliasPhotonScatter; |
2027 |
< |
photonScatter [MAT_BRTDF] = brtdFuncPhotonScatter; |
2028 |
< |
photonScatter [MAT_BSDF] = |
2029 |
< |
photonScatter [MAT_ABSDF] = bsdfPhotonScatter; |
2027 |
> |
photonScatter [MAT_BRTDF] = brdfPhotonScatter; |
2028 |
> |
|
2029 |
> |
photonScatter [MAT_PFUNC] = photonScatter [MAT_MFUNC] = |
2030 |
> |
photonScatter [MAT_PDATA] = photonScatter [MAT_MDATA] = |
2031 |
> |
photonScatter [MAT_TFUNC] = photonScatter [MAT_TDATA] = |
2032 |
> |
brdf2PhotonScatter; |
2033 |
> |
|
2034 |
> |
photonScatter [MAT_BSDF] = photonScatter [MAT_ABSDF] = |
2035 |
> |
bsdfPhotonScatter; |
2036 |
|
} |