46 |
|
COLOR mcolor, scolor; |
47 |
|
FVECT vrefl, prdir, pnorm; |
48 |
|
double alpha2, rdiff, rspec, trans, tdiff, tspec, pdot; |
49 |
< |
} NORMDAT; |
49 |
> |
} NORMDAT; |
50 |
|
|
51 |
|
typedef struct { |
52 |
|
OBJREC *mp; |
55 |
|
COLOR mcolor, scolor; |
56 |
|
FVECT vrefl, prdir, u, v, pnorm; |
57 |
|
double u_alpha, v_alpha, rdiff, rspec, trans, tdiff, tspec, pdot; |
58 |
< |
} ANISODAT; |
58 |
> |
} ANISODAT; |
59 |
|
|
60 |
|
typedef struct { |
61 |
|
OBJREC *mp; |
69 |
|
double tspec; |
70 |
|
FVECT pnorm; |
71 |
|
double pdot; |
72 |
< |
} BRDFDAT; |
72 |
> |
} BRDFDAT; |
73 |
|
|
74 |
|
typedef struct { |
75 |
|
OBJREC *mp; |
1475 |
|
|
1476 |
|
|
1477 |
|
|
1478 |
< |
static int brtdFuncPhotonScatter (OBJREC *mat, RAY *rayIn) |
1479 |
< |
/* Generate new photon ray for BRTDfunc material and recurse */ |
1478 |
> |
static int brdfPhotonScatter (OBJREC *mat, RAY *rayIn) |
1479 |
> |
/* Generate new photon ray for BRTDfunc material and recurse. Only ideal |
1480 |
> |
reflection and transmission are sampled for the specular componentent. */ |
1481 |
|
{ |
1482 |
|
int hitfront = 1, hastexture, i; |
1483 |
|
BRDFDAT nd; |
1487 |
|
MFUNC *mf; |
1488 |
|
FVECT bnorm; |
1489 |
|
|
1490 |
+ |
/* Check argz */ |
1491 |
|
if (mat -> oargs.nsargs < 10 || mat -> oargs.nfargs < 9) |
1492 |
|
objerror(mat, USER, "bad # arguments"); |
1493 |
|
nd.mp = mat; |
1494 |
|
nd.pr = rayIn; |
1495 |
< |
/* Dummies */ |
1495 |
> |
/* Dummiez */ |
1496 |
|
nd.rspec = nd.tspec = 1.0; |
1497 |
|
nd.trans = 0.5; |
1498 |
|
|
1499 |
< |
/* Diffuse reflectance */ |
1499 |
> |
/* Diffuz reflektanz */ |
1500 |
|
if (rayIn -> rod > 0.0) |
1501 |
|
setcolor(nd.rdiff, mat -> oargs.farg[0], mat -> oargs.farg [1], |
1502 |
|
mat -> oargs.farg [2]); |
1503 |
|
else |
1504 |
|
setcolor(nd.rdiff, mat-> oargs.farg [3], mat -> oargs.farg [4], |
1505 |
|
mat -> oargs.farg [5]); |
1506 |
< |
/* Diffuse transmittance */ |
1506 |
> |
/* Diffuz tranzmittanz */ |
1507 |
|
setcolor(nd.tdiff, mat -> oargs.farg [6], mat -> oargs.farg [7], |
1508 |
|
mat -> oargs.farg [8]); |
1509 |
|
|
1510 |
< |
/* Get modifiers */ |
1510 |
> |
/* Get modz */ |
1511 |
|
raytexture(rayIn, mat -> omod); |
1512 |
|
hastexture = (DOT(rayIn -> pert, rayIn -> pert) > sqr(FTINY)); |
1513 |
|
if (hastexture) { |
1520 |
|
} |
1521 |
|
|
1522 |
|
if (rayIn -> rod < 0.0) { |
1523 |
< |
/* Orient perturbed values */ |
1523 |
> |
/* Orient perturbed valuz */ |
1524 |
|
nd.pdot = -nd.pdot; |
1525 |
|
for (i = 0; i < 3; i++) { |
1526 |
|
nd.pnorm [i] = -nd.pnorm [i]; |
1530 |
|
hitfront = 0; |
1531 |
|
} |
1532 |
|
|
1533 |
< |
/* Get pattern color, modify diffuse values */ |
1533 |
> |
/* Get pattern kolour, modify diffuz valuz */ |
1534 |
|
copycolor(nd.mcolor, rayIn -> pcol); |
1535 |
|
multcolor(nd.rdiff, nd.mcolor); |
1536 |
|
multcolor(nd.tdiff, nd.mcolor); |
1537 |
|
|
1538 |
< |
/* Load cal file, evaluate spec refl/trans vars */ |
1538 |
> |
/* Load cal file, evaluate spekula refl/tranz varz */ |
1539 |
|
nd.dp = NULL; |
1540 |
|
mf = getfunc(mat, 9, 0x3f, 0); |
1541 |
|
setbrdfunc(&nd); |
1547 |
|
if (errno == EDOM || errno == ERANGE) |
1548 |
|
objerror(mat, WARNING, "compute error"); |
1549 |
|
else { |
1550 |
< |
/* Set up probabilities */ |
1550 |
> |
/* Set up probz */ |
1551 |
|
prDiff = colorAvg(nd.rdiff); |
1552 |
|
ptDiff = colorAvg(nd.tdiff); |
1553 |
|
prSpec = colorAvg(rspecCol); |
1555 |
|
albedo = prDiff + ptDiff + prSpec + ptSpec; |
1556 |
|
} |
1557 |
|
|
1558 |
< |
/* Insert direct and indirect photon hits if diffuse component */ |
1558 |
> |
/* Insert direct and indirect photon hitz if diffuz komponent */ |
1559 |
|
if (prDiff > FTINY || ptDiff > FTINY) |
1560 |
|
addPhotons(rayIn); |
1561 |
|
|
1562 |
< |
/* Stochastically sample absorption or scattering events */ |
1562 |
> |
/* Stochastically sample absorption or scattering evenz */ |
1563 |
|
if ((xi = pmapRandom(rouletteState)) > albedo) |
1564 |
|
/* Absorbed */ |
1565 |
|
return 0; |
1566 |
|
|
1567 |
|
if (xi > (albedo -= prSpec)) { |
1568 |
< |
/* Specular reflection */ |
1568 |
> |
/* Ideal spekula reflekzion */ |
1569 |
|
photonRay(rayIn, &rayOut, PMAP_SPECREFL, rspecCol); |
1570 |
|
VSUM(rayOut.rdir, rayIn -> rdir, nd.pnorm, 2 * nd.pdot); |
1571 |
|
checknorm(rayOut.rdir); |
1572 |
|
} |
1573 |
|
else if (xi > (albedo -= ptSpec)) { |
1574 |
< |
/* Specular transmission */ |
1574 |
> |
/* Ideal spekula tranzmission */ |
1575 |
|
photonRay(rayIn, &rayOut, PMAP_SPECTRANS, tspecCol); |
1576 |
|
if (hastexture) { |
1577 |
< |
/* Perturb direction */ |
1577 |
> |
/* Perturb direkzion */ |
1578 |
|
VSUB(rayOut.rdir, rayIn -> rdir, rayIn -> pert); |
1579 |
|
if (normalize(rayOut.rdir) == 0.0) { |
1580 |
|
objerror(mat, WARNING, "illegal perturbation"); |
1584 |
|
} |
1585 |
|
} |
1586 |
|
else if (xi > (albedo -= prDiff)) { |
1587 |
< |
/* Diffuse reflection */ |
1587 |
> |
/* Diffuz reflekzion */ |
1588 |
|
if (!hitfront) |
1589 |
|
flipsurface(rayIn); |
1590 |
|
photonRay(rayIn, &rayOut, PMAP_DIFFREFL, nd.mcolor); |
1591 |
|
diffPhotonScatter(nd.pnorm, &rayOut); |
1592 |
|
} |
1593 |
|
else { |
1594 |
< |
/* Diffuse transmission */ |
1594 |
> |
/* Diffuz tranzmission */ |
1595 |
|
if (hitfront) |
1596 |
|
flipsurface(rayIn); |
1597 |
|
photonRay(rayIn, &rayOut, PMAP_DIFFTRANS, nd.mcolor); |
1601 |
|
diffPhotonScatter(bnorm, &rayOut); |
1602 |
|
} |
1603 |
|
|
1604 |
+ |
tracePhoton(&rayOut); |
1605 |
|
return 0; |
1606 |
|
} |
1607 |
|
|
1608 |
|
|
1609 |
|
|
1610 |
< |
#if 0 |
1611 |
< |
int |
1612 |
< |
m_brdf2( /* color a ray that hit a BRDF material */ |
1610 |
< |
OBJREC *m, |
1611 |
< |
RAY *r |
1612 |
< |
) |
1610 |
> |
int brdf2PhotonScatter (OBJREC *mat, RAY *rayIn) |
1611 |
> |
/* Generate new photon ray for procedural or data driven BRDF material and |
1612 |
> |
recurse. Only diffuse reflection and transmission are sampled. */ |
1613 |
|
{ |
1614 |
< |
BRDFDAT nd; |
1615 |
< |
COLOR ctmp; |
1616 |
< |
FVECT vtmp; |
1617 |
< |
double dtmp; |
1618 |
< |
/* 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); |
1614 |
> |
BRDFDAT nd; |
1615 |
> |
RAY rayOut; |
1616 |
> |
double dtmp, prDiff, ptDiff, albedo, xi; |
1617 |
> |
MFUNC *mf; |
1618 |
> |
FVECT bnorm; |
1619 |
|
|
1620 |
< |
nd.mp = m; |
1621 |
< |
nd.pr = r; |
1622 |
< |
/* get material color */ |
1623 |
< |
setcolor(nd.mcolor, m->oargs.farg[0], |
1624 |
< |
m->oargs.farg[1], |
1625 |
< |
m->oargs.farg[2]); |
1626 |
< |
/* get specular component */ |
1627 |
< |
nd.rspec = m->oargs.farg[3]; |
1628 |
< |
/* compute transmittance */ |
1629 |
< |
if ((m->otype == MAT_TFUNC) | (m->otype == MAT_TDATA)) { |
1630 |
< |
nd.trans = m->oargs.farg[4]*(1.0 - nd.rspec); |
1631 |
< |
nd.tspec = nd.trans * m->oargs.farg[5]; |
1632 |
< |
dtmp = nd.trans - nd.tspec; |
1633 |
< |
setcolor(nd.tdiff, dtmp, dtmp, dtmp); |
1634 |
< |
} else { |
1635 |
< |
nd.tspec = nd.trans = 0.0; |
1636 |
< |
setcolor(nd.tdiff, 0.0, 0.0, 0.0); |
1637 |
< |
} |
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); |
1620 |
> |
/* Check argz */ |
1621 |
> |
if (mat -> oargs.nsargs < (hasdata(mat -> otype) ? 4 : 2) || |
1622 |
> |
mat -> oargs.nfargs < (mat -> otype == MAT_TFUNC || |
1623 |
> |
mat -> otype == MAT_TDATA ? 6 : 4)) |
1624 |
> |
objerror(mat, USER, "bad # arguments"); |
1625 |
> |
|
1626 |
> |
if (rayIn -> rod < 0.0) { |
1627 |
> |
/* Hit backside; reorient if visible, else transfer photon */ |
1628 |
> |
if (!backvis) { |
1629 |
> |
photonRay(rayIn, &rayOut, PMAP_XFER, NULL); |
1630 |
> |
tracePhoton(&rayOut); |
1631 |
> |
return 0; |
1632 |
> |
} |
1633 |
> |
|
1634 |
> |
raytexture(rayIn, mat -> omod); |
1635 |
> |
flipsurface(rayIn); |
1636 |
> |
} |
1637 |
> |
else raytexture(rayIn, mat -> omod); |
1638 |
|
|
1639 |
< |
return(1); |
1639 |
> |
nd.mp = mat; |
1640 |
> |
nd.pr = rayIn; |
1641 |
> |
/* Material kolour */ |
1642 |
> |
setcolor(nd.mcolor, mat -> oargs.farg [0], mat -> oargs.farg [1], |
1643 |
> |
mat -> oargs.farg [2]); |
1644 |
> |
/* Spekula komponent */ |
1645 |
> |
nd.rspec = mat -> oargs.farg [3]; |
1646 |
> |
|
1647 |
> |
/* Tranzmittanz */ |
1648 |
> |
if (mat -> otype == MAT_TFUNC || mat -> otype == MAT_TDATA) { |
1649 |
> |
nd.trans = mat -> oargs.farg [4] * (1.0 - nd.rspec); |
1650 |
> |
nd.tspec = nd.trans * mat -> oargs.farg [5]; |
1651 |
> |
dtmp = nd.trans - nd.tspec; |
1652 |
> |
setcolor(nd.tdiff, dtmp, dtmp, dtmp); |
1653 |
> |
} |
1654 |
> |
else { |
1655 |
> |
nd.tspec = nd.trans = 0.0; |
1656 |
> |
setcolor(nd.tdiff, 0.0, 0.0, 0.0); |
1657 |
> |
} |
1658 |
> |
|
1659 |
> |
/* Reflektanz */ |
1660 |
> |
dtmp = 1.0 - nd.trans - nd.rspec; |
1661 |
> |
setcolor(nd.rdiff, dtmp, dtmp, dtmp); |
1662 |
> |
/* Perturb normal */ |
1663 |
> |
nd.pdot = raynormal(nd.pnorm, rayIn); |
1664 |
> |
/* Modify material kolour */ |
1665 |
> |
multcolor(nd.mcolor, rayIn -> pcol); |
1666 |
> |
multcolor(nd.rdiff, nd.mcolor); |
1667 |
> |
multcolor(nd.tdiff, nd.mcolor); |
1668 |
> |
|
1669 |
> |
/* Load auxiliary filez */ |
1670 |
> |
if (hasdata(mat -> otype)) { |
1671 |
> |
nd.dp = getdata(mat -> oargs.sarg [1]); |
1672 |
> |
getfunc(mat, 2, 0, 0); |
1673 |
> |
} |
1674 |
> |
else { |
1675 |
> |
nd.dp = NULL; |
1676 |
> |
getfunc(mat, 1, 0, 0); |
1677 |
> |
} |
1678 |
> |
|
1679 |
> |
/* Set up probz */ |
1680 |
> |
prDiff = colorAvg(nd.rdiff); |
1681 |
> |
ptDiff = colorAvg(nd.tdiff); |
1682 |
> |
albedo = prDiff + ptDiff; |
1683 |
> |
|
1684 |
> |
/* Insert direct and indirect photon hitz if diffuz komponent */ |
1685 |
> |
if (prDiff > FTINY || ptDiff > FTINY) |
1686 |
> |
addPhotons(rayIn); |
1687 |
> |
|
1688 |
> |
/* Stochastically sample absorption or scattering evenz */ |
1689 |
> |
if ((xi = pmapRandom(rouletteState)) > albedo) |
1690 |
> |
/* Absorbed */ |
1691 |
> |
return 0; |
1692 |
> |
|
1693 |
> |
if (xi > (albedo -= prDiff)) { |
1694 |
> |
/* Diffuz reflekzion */ |
1695 |
> |
photonRay(rayIn, &rayOut, PMAP_DIFFREFL, nd.rdiff); |
1696 |
> |
diffPhotonScatter(nd.pnorm, &rayOut); |
1697 |
> |
} |
1698 |
> |
else { |
1699 |
> |
/* Diffuz tranzmission */ |
1700 |
> |
flipsurface(rayIn); |
1701 |
> |
photonRay(rayIn, &rayOut, PMAP_DIFFTRANS, nd.tdiff); |
1702 |
> |
bnorm [0] = -nd.pnorm [0]; |
1703 |
> |
bnorm [1] = -nd.pnorm [1]; |
1704 |
> |
bnorm [2] = -nd.pnorm [2]; |
1705 |
> |
diffPhotonScatter(bnorm, &rayOut); |
1706 |
> |
} |
1707 |
> |
|
1708 |
> |
tracePhoton(&rayOut); |
1709 |
> |
return 0; |
1710 |
|
} |
1692 |
– |
#endif |
1711 |
|
|
1712 |
|
|
1713 |
|
|
1971 |
|
/* Init photonScatter[] dispatch table */ |
1972 |
|
{ |
1973 |
|
int i; |
1974 |
< |
|
1974 |
> |
|
1975 |
|
/* Catch-all for inconsistencies */ |
1976 |
|
for (i = 0; i < NUMOTYPE; i++) |
1977 |
|
photonScatter [i] = o_default; |
1978 |
< |
|
1978 |
> |
|
1979 |
|
photonScatter [MAT_LIGHT] = photonScatter [MAT_ILLUM] = |
1980 |
|
photonScatter [MAT_GLOW] = photonScatter [MAT_SPOT] = |
1981 |
|
lightPhotonScatter; |
1982 |
< |
|
1982 |
> |
|
1983 |
|
photonScatter [MAT_PLASTIC] = photonScatter [MAT_METAL] = |
1984 |
|
photonScatter [MAT_TRANS] = normalPhotonScatter; |
1985 |
|
|
1988 |
|
|
1989 |
|
photonScatter [MAT_DIELECTRIC] = photonScatter [MAT_INTERFACE] = |
1990 |
|
dielectricPhotonScatter; |
1991 |
< |
|
1991 |
> |
|
1992 |
|
photonScatter [MAT_MIST] = mistPhotonScatter; |
1993 |
|
photonScatter [MAT_GLASS] = glassPhotonScatter; |
1994 |
|
photonScatter [MAT_CLIP] = clipPhotonScatter; |
1996 |
|
photonScatter [MIX_FUNC] = mx_funcPhotonScatter; |
1997 |
|
photonScatter [MIX_DATA] = mx_dataPhotonScatter; |
1998 |
|
photonScatter [MIX_PICT]= mx_pdataPhotonScatter; |
1999 |
< |
|
1999 |
> |
|
2000 |
|
photonScatter [PAT_BDATA] = photonScatter [PAT_CDATA] = |
2001 |
|
photonScatter [PAT_BFUNC] = photonScatter [PAT_CFUNC] = |
2002 |
|
photonScatter [PAT_CPICT] = photonScatter [TEX_FUNC] = |
2003 |
|
photonScatter [TEX_DATA] = pattexPhotonScatter; |
2004 |
< |
|
2004 |
> |
|
2005 |
|
photonScatter [MOD_ALIAS] = aliasPhotonScatter; |
2006 |
< |
photonScatter [MAT_BRTDF] = brtdFuncPhotonScatter; |
2007 |
< |
photonScatter [MAT_BSDF] = |
2008 |
< |
photonScatter [MAT_ABSDF] = bsdfPhotonScatter; |
2006 |
> |
photonScatter [MAT_BRTDF] = brdfPhotonScatter; |
2007 |
> |
|
2008 |
> |
photonScatter [MAT_PFUNC] = photonScatter [MAT_MFUNC] = |
2009 |
> |
photonScatter [MAT_PDATA] = photonScatter [MAT_MDATA] = |
2010 |
> |
photonScatter [MAT_TFUNC] = photonScatter [MAT_TDATA] = |
2011 |
> |
brdf2PhotonScatter; |
2012 |
> |
|
2013 |
> |
photonScatter [MAT_BSDF] = photonScatter [MAT_ABSDF] = |
2014 |
> |
bsdfPhotonScatter; |
2015 |
|
} |