ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapmat.c
(Generate patch)

Comparing ray/src/rt/pmapmat.c (file contents):
Revision 2.1 by greg, Tue Feb 24 19:39:27 2015 UTC vs.
Revision 2.2 by rschregle, Wed Apr 22 15:50:44 2015 UTC

# Line 113 | Line 113 | void photonRay (const RAY *rayIn, RAY *rayOut,
113        VCOPY(rayOut -> rdir, rayIn -> rdir);
114     }
115     else if (fluxAtten) {
116 <      /* Attenuate and normalised flux for scattered rays */
116 >      /* Attenuate and normalise flux for scattered rays */
117        multcolor(rayOut -> rcol, fluxAtten);
118        colorNorm(rayOut -> rcol);
119     }
# Line 1383 | Line 1383 | static int pattexPhotonScatter (OBJREC *mat, RAY *rayI
1383  
1384  
1385  
1386 + #if 0
1387 +   static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn)
1388 +   /* Generate new photon ray for BSDF modifier and recurse. */
1389 +   {
1390 +      int      hitFront;
1391 +      SDError  err;
1392 +      FVECT        upvec;
1393 +      MFUNC        *mf;
1394 +      BSDFDAT   nd;
1395 +      RAY      rayOut;
1396 +
1397 +      /* Following code adapted from m_bsdf() */
1398 +      /* Check arguments */
1399 +      if (mat -> oargs.nsargs < 6 || mat -> oargs.nfargs > 9 ||
1400 +          mat -> oargs.nfargs % 3)
1401 +         objerror(mat, USER, "bad # arguments");
1402 +        
1403 +      hitFront = (rayIn -> rod > 0);
1404 +
1405 +      /* Load cal file */
1406 +      mf = getfunc(mat, 5, 0x1d, 1);
1407 +      
1408 +      /* Get thickness */
1409 +      nd.thick = evalue(mf -> ep [0]);
1410 +      if ((-FTINY <= nd.thick) & (nd.thick <= FTINY))
1411 +         nd.thick = .0;
1412 +        
1413 +      if (nd.thick != .0 || (!hitFront && !backvis)) {
1414 +         /* Proxy geometry present, so use it instead and transfer ray */
1415 +         photonRay(rayIn, &rayOut, PMAP_XFER, NULL);
1416 +         tracePhoton(&rayOut);
1417 +        
1418 +         return 0;
1419 +      }
1420 +
1421 +      /* Get BSDF data */
1422 +      nd.sd = loadBSDF(mat -> oargs.sarg [1]);
1423 +      
1424 +      /* Diffuse reflectance */
1425 +      if (hitFront) {
1426 +         if (mat -> oargs.nfargs < 3)
1427 +            setcolor(nd.rdiff, .0, .0, .0);
1428 +         else setcolor(nd.rdiff, mat -> oargs.farg [0], mat -> oargs.farg [1],
1429 +                       mat -> oargs.farg [2]);
1430 +      }    
1431 +      else if (mat -> oargs.nfargs < 6) {
1432 +         /* Check for absorbing backside */
1433 +         if (!backvis && !nd.sd -> rb && !nd.sd -> tf) {
1434 +            SDfreeCache(nd.sd);                    
1435 +            return 0;
1436 +         }
1437 +        
1438 +         setcolor(nd.rdiff, .0, .0, .0);
1439 +      }
1440 +      else setcolor(nd.rdiff, mat -> oargs.farg [3], mat -> oargs.farg [4],
1441 +                    mat -> oargs.farg [5]);
1442 +
1443 +      /* Diffuse transmittance */
1444 +      if (mat -> oargs.nfargs < 9)
1445 +         setcolor(nd.tdiff, .0, .0, .0);
1446 +      else setcolor(nd.tdiff, mat -> oargs.farg [6], mat -> oargs.farg [7],
1447 +                    mat -> oargs.farg [8]);
1448 +                  
1449 +      nd.mp = mat;
1450 +      nd.pr = rayIn;
1451 +      
1452 +      /* Get modifiers */
1453 +      raytexture(rayIn, mat -> omod);
1454 +      
1455 +      /* Modify diffuse values */
1456 +      multcolor(nd.rdiff, rayIn -> pcol);
1457 +      multcolor(nd.tdiff, rayIn -> pcol);
1458 +        
1459 +      /* Get up vector & xform to world coords */
1460 +      upvec [0] = evalue(mf -> ep [1]);
1461 +      upvec [1] = evalue(mf -> ep [2]);
1462 +      upvec [2] = evalue(mf -> ep [3]);
1463 +      
1464 +      if (mf -> fxp != &unitxf) {
1465 +         multv3(upvec, upvec, mf -> fxp -> xfm);
1466 +         nd.thick *= mf -> fxp -> sca;
1467 +      }
1468 +      
1469 +      if (rayIn -> rox) {
1470 +         multv3(upvec, upvec, rayIn -> rox -> f.xfm);
1471 +         nd.thick *= rayIn -> rox -> f.sca;
1472 +      }
1473 +      
1474 +      /* Perturb normal */
1475 +      raynormal(nd.pnorm, rayIn);
1476 +      
1477 +      /* Xform incident dir to local BSDF coords */
1478 +      err = SDcompXform(nd.toloc, nd.pnorm, upvec);
1479 +      
1480 +      if (!err) {
1481 +         nd.vray [0] = -rayIn -> rdir [0];
1482 +         nd.vray [1] = -rayIn -> rdir [1];
1483 +         nd.vray [2] = -rayIn -> rdir [2];
1484 +         err = SDmapDir(nd.vray, nd.toloc, nd.vray);
1485 +      }
1486 +      
1487 +      if (!err)
1488 +         err = SDinvXform(nd.fromloc, nd.toloc);
1489 +        
1490 +      if (err) {
1491 +         objerror(mat, WARNING, "Illegal orientation vector");
1492 +         return 0;
1493 +      }
1494 +      
1495 +      /* Determine BSDF resolution */
1496 +      err = SDsizeBSDF(nd.sr_vpsa, nd.vray, NULL, SDqueryMin + SDqueryMax, nd.sd);
1497 +      
1498 +      if (err)
1499 +         objerror(mat, USER, transSDError(err));
1500 +        
1501 +      nd.sr_vpsa [0] = sqrt(nd.sr_vpsa [0]);
1502 +      nd.sr_vpsa [1] = sqrt(nd.sr_vpsa [1]);
1503 +
1504 +      /* Orient perturbed normal towards incident side */
1505 +      if (!hitFront) {                  
1506 +         nd.pnorm [0] = -nd.pnorm [0];
1507 +         nd.pnorm [1] = -nd.pnorm [1];
1508 +         nd.pnorm [2] = -nd.pnorm [2];
1509 +      }
1510 +      
1511 +      /* Following code adapted from SDsampBSDF() */
1512 +      {
1513 +         SDSpectralDF   *rdf, *tdf;
1514 +         SDValue        bsdfVal;
1515 +         double         xi, rhoDiff = 0;
1516 +         float          coef [SDmaxCh];
1517 +         int            i, j, n, nr;
1518 +         SDComponent       *sdc;
1519 +         const SDCDst   **cdarr = NULL;
1520 +        
1521 +         /* Get diffuse albedo (?) */
1522 +         if (hitFront) {
1523 +            bsdfVal = nd.sd -> rLambFront;
1524 +            rdf = nd.sd -> rf;
1525 +            tdf = nd.sd -> tf ? nd.sd -> tf : nd.sd -> tb;
1526 +         }
1527 +         else {
1528 +            bsdfVal = nd.sd -> rLambBack;
1529 +            rdf = nd.sd -> rb;
1530 +            tdf = nd.sd -> tb ? nd.sd -> tb : nd.sd -> tf;
1531 +         }
1532 +        
1533 +         rhoDiff = bsdfVal.cieY;
1534 +         bsdfVal.cieY += nd.sd -> tLamb.cieY;
1535 +        
1536 +         /* Allocate non-diffuse sampling */
1537 +         i = nr = rdf ? rdf -> ncomp : 0;
1538 +         j = tdf ? tdf -> ncomp : 0;
1539 +         n = i + j;
1540 +        
1541 +         if (n > 0 && !(cdarr = (const SDCDst**)malloc(n * sizeof(SDCDst*))))
1542 +            objerror(mat, USER, transSDError(SDEmemory));
1543 +            
1544 +         while (j-- > 0) {
1545 +            /* Sum up non-diffuse transmittance */
1546 +            cdarr [i + j] = (*tdf -> comp [j].func -> getCDist)(nd.vray, &tdf -> comp [j]);
1547 +            
1548 +            if (!cdarr [i + j])
1549 +               cdarr [i + j] = &SDemptyCD;
1550 +            else bsdfVal.cieY += cdarr [i + j] -> cTotal;
1551 +         }
1552 +        
1553 +         while (i-- > 0) {
1554 +            /* Sum up non-diffuse reflectance */
1555 +            cdarr [i] = (*rdf -> comp [i].func -> getCDist)(nd.vray, &rdf -> comp [i]);
1556 +            
1557 +            if (!cdarr [i])
1558 +               cdarr [i] = &SDemptyCD;
1559 +            else bsdfVal.cieY += cdarr [i] -> cTotal;
1560 +         }
1561 +        
1562 +         if (bsdfVal.cieY <= FTINY) {
1563 +            /* Don't bother sampling, just absorb photon */
1564 +            if (cdarr)
1565 +               free(cdarr);
1566 +            return 0;
1567 +         }      
1568 +        
1569 +         /* Insert direct and indirect photon hits if diffuse component */
1570 +         if (rhoDiff > FTINY || nd.sd -> tLamb.cieY > FTINY)
1571 +            addPhotons(rayIn);  
1572 +            
1573 +         xi = pmapRandom(rouletteState);
1574 +        
1575 +         if ((xi -= rhoDiff) <= 0) {
1576 +            /* Diffuse reflection */
1577 +            photonRay(rayIn, &rayOut, PMAP_DIFFREFL, nd.rdiff);
1578 +            diffPhotonScatter(nd.pnorm, &rayOut);
1579 +         }
1580 +         else if ((xi -= nd.sd -> tLamb.cieY) <= 0) {
1581 +            /* Diffuse transmission */
1582 +            flipsurface(rayIn);
1583 +            photonRay(rayIn, &rayOut, PMAP_DIFFTRANS, nd.tdiff);
1584 +            bsdfVal.spec = nd.sd -> tLamb.spec;
1585 +            diffPhotonScatter(nd.pnorm, &rayOut);
1586 +         }
1587 +         else {
1588 +            int rayOutType;
1589 +            COLOR bsdfRGB;
1590 +              
1591 +            /* Non-diffuse CDF inversion (?) */
1592 +            for (i = 0; i < n && (xi -= cdarr [i] -> cTotal) > 0; i++);
1593 +            
1594 +            if (i >= n) {
1595 +               /* Absorbed -- photon went Deer Hunter */
1596 +               if (cdarr)
1597 +                  free(cdarr);
1598 +               return 0;
1599 +            }
1600 +
1601 +            if (i < nr) {
1602 +               /* Non-diffuse reflection */
1603 +               sdc = &rdf -> comp [i];
1604 +               rayOutType = PMAP_SPECREFL;
1605 +            }
1606 +            else {
1607 +               /* Non-diffuse transmission */
1608 +               sdc = &tdf -> comp [i - nr];
1609 +               rayOutType = PMAP_SPECTRANS;
1610 +            }
1611 +            
1612 +            /* Generate non-diff sample dir */
1613 +            VCOPY(rayOut.rdir, nd.vray);
1614 +            err = (*sdc -> func -> sampCDist)
1615 +                  (rayOut.rdir, pmapRandom(scatterState), cdarr [i]);              
1616 +            if (err)
1617 +               objerror(mat, USER, transSDError(SDEinternal));
1618 +
1619 +            /* Get colour */
1620 +            j = (*sdc -> func -> getBSDFs)(coef, rayOut.rdir, nd.vray, sdc);
1621 +            
1622 +            if (j <= 0) {
1623 +               sprintf(SDerrorDetail, "BSDF \"%s\" sampling value error",
1624 +                       nd.sd -> name);
1625 +               objerror(mat, USER, transSDError(SDEinternal));
1626 +            }
1627 +            
1628 +            bsdfVal.spec = sdc -> cspec [0];
1629 +            rhoDiff = coef [0];
1630 +            
1631 +            while (--j) {
1632 +               c_cmix(&bsdfVal.spec, rhoDiff, &bsdfVal.spec, coef [j],
1633 +                      &sdc -> cspec [j]);
1634 +               rhoDiff += coef [j];
1635 +            }
1636 +            
1637 +            /* ? */
1638 +            c_ccvt(&bsdfVal.spec, C_CSXY + C_CSSPEC);
1639 +            ccy2rgb(&bsdfVal.spec, bsdfVal.cieY, bsdfRGB);
1640 +            
1641 +            /* Xform outgoing dir to world coords */
1642 +            if ((err = SDmapDir(rayOut.rdir, nd.fromloc, rayOut.rdir))) {
1643 +               objerror(mat, USER, transSDError(err));
1644 +               return 0;
1645 +            }
1646 +            
1647 +            photonRay(rayIn, &rayOut, rayOutType, bsdfRGB);
1648 +         }
1649 +        
1650 +         if (cdarr)
1651 +            free(cdarr);
1652 +      }
1653 +                          
1654 +      /* Clean up BSDF */
1655 +      SDfreeCache(nd.sd);
1656 +
1657 +      tracePhoton(&rayOut);
1658 +      return 0;
1659 +   }
1660 + #else
1661 +
1662   static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn)
1663   /* Generate new photon ray for BSDF modifier and recurse. */
1664   {
1665     int      hitFront;
1666     SDError  err;
1667 +   SDValue  bsdfVal;
1668     FVECT           upvec;
1669     MFUNC           *mf;
1670     BSDFDAT      nd;
1671     RAY      rayOut;
1672 <
1672 >   COLOR    bsdfRGB;
1673 >   double   prDiff, ptDiff, prDiffSD, ptDiffSD, prSpecSD, ptSpecSD,
1674 >            albedo, xi, xi2;
1675 >   const double patAlb = colorAvg(rayIn -> pcol);
1676 >  
1677     /* Following code adapted from m_bsdf() */
1678     /* Check arguments */
1679     if (mat -> oargs.nsargs < 6 || mat -> oargs.nfargs > 9 ||
# Line 1420 | Line 1701 | static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn)
1701     /* Get BSDF data */
1702     nd.sd = loadBSDF(mat -> oargs.sarg [1]);
1703    
1704 <   /* Diffuse reflectance */
1704 >   /* Extra diffuse reflectance from material def */
1705     if (hitFront) {
1706        if (mat -> oargs.nfargs < 3)
1707           setcolor(nd.rdiff, .0, .0, .0);
# Line 1439 | Line 1720 | static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn)
1720     else setcolor(nd.rdiff, mat -> oargs.farg [3], mat -> oargs.farg [4],
1721                   mat -> oargs.farg [5]);
1722  
1723 <        /* Diffuse transmittance */
1723 >        /* Extra diffuse transmittance from material def */
1724          if (mat -> oargs.nfargs < 9)
1725             setcolor(nd.tdiff, .0, .0, .0);
1726     else setcolor(nd.tdiff, mat -> oargs.farg [6], mat -> oargs.farg [7],
# Line 1506 | Line 1787 | static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn)
1787        nd.pnorm [1] = -nd.pnorm [1];
1788        nd.pnorm [2] = -nd.pnorm [2];
1789     }
1790 <  
1791 <   /* Following code adapted from SDsampBSDF() */
1792 <   {
1793 <      SDSpectralDF   *rdf, *tdf;
1794 <      SDValue        bsdfVal;
1795 <      double         xi, rhoDiff = 0;
1796 <      float          coef [SDmaxCh];
1797 <      int            i, j, n, nr;
1798 <      SDComponent          *sdc;
1799 <      const SDCDst   **cdarr = NULL;
1800 <      
1801 <      /* Get diffuse albedo (?) */
1802 <      if (hitFront) {
1803 <         bsdfVal = nd.sd -> rLambFront;
1804 <         rdf = nd.sd -> rf;
1805 <         tdf = nd.sd -> tf ? nd.sd -> tf : nd.sd -> tb;
1806 <      }
1807 <      else {
1527 <         bsdfVal = nd.sd -> rLambBack;
1528 <         rdf = nd.sd -> rb;
1529 <         tdf = nd.sd -> tb ? nd.sd -> tb : nd.sd -> tf;
1530 <      }
1531 <      
1532 <      rhoDiff = bsdfVal.cieY;
1533 <      bsdfVal.cieY += nd.sd -> tLamb.cieY;
1534 <      
1535 <      /* Allocate non-diffuse sampling */
1536 <      i = nr = rdf ? rdf -> ncomp : 0;
1537 <      j = tdf ? tdf -> ncomp : 0;
1538 <      n = i + j;
1539 <      
1540 <      if (n > 0 && !(cdarr = (const SDCDst**)malloc(n * sizeof(SDCDst*))))
1541 <         objerror(mat, USER, transSDError(SDEmemory));
1790 >
1791 >   /* Get scatter probabilities (weighted by pattern except for spec refl)
1792 >    * prDiff, ptDiff:      extra diffuse component in material def
1793 >    * prDiffSD, ptDiffSD:  diffuse (constant) component in SDF
1794 >    * prSpecSD, ptSpecSD:  non-diffuse ("specular") component in SDF
1795 >    * albedo:              sum of above, inverse absorption probability */
1796 >   prDiff   = colorAvg(nd.rdiff);
1797 >   ptDiff   = colorAvg(nd.tdiff);
1798 >   prDiffSD = patAlb * SDdirectHemi(nd.vray, SDsampDf | SDsampR, nd.sd);
1799 >   ptDiffSD = patAlb * SDdirectHemi(nd.vray, SDsampDf | SDsampT, nd.sd);
1800 >   prSpecSD = SDdirectHemi(nd.vray, SDsampSp | SDsampR, nd.sd);
1801 >   ptSpecSD = patAlb * SDdirectHemi(nd.vray, SDsampSp | SDsampT, nd.sd);
1802 >   albedo   = prDiff + ptDiff + prDiffSD + ptDiffSD + prSpecSD + ptSpecSD;
1803 >
1804 >   /*    
1805 >   if (albedo > 1)
1806 >      objerror(mat, WARNING, "Invalid albedo");
1807 >   */
1808          
1809 <      while (j-- > 0) {
1810 <         /* Sum up non-diffuse transmittance */
1811 <         cdarr [i + j] = (*tdf -> comp [j].func -> getCDist)(nd.vray, &tdf -> comp [j]);
1812 <        
1813 <         if (!cdarr [i + j])
1548 <            cdarr [i + j] = &SDemptyCD;
1549 <         else bsdfVal.cieY += cdarr [i + j] -> cTotal;
1550 <      }
1809 >   /* Insert direct and indirect photon hits if diffuse component */
1810 >   if (prDiff + ptDiff + prDiffSD + ptDiffSD > FTINY)
1811 >      addPhotons(rayIn);        
1812 >
1813 >   xi = xi2 = pmapRandom(rouletteState);
1814        
1815 <      while (i-- > 0) {
1816 <         /* Sum up non-diffuse reflectance */
1817 <         cdarr [i] = (*rdf -> comp [i].func -> getCDist)(nd.vray, &rdf -> comp [i]);
1815 >   if (xi > albedo)
1816 >      /* Absorbtion */
1817 >      return 0;
1818 >  
1819 >   if ((xi -= prDiff) <= 0) {
1820 >      /* Diffuse reflection (extra component in material def) */
1821 >      photonRay(rayIn, &rayOut, PMAP_DIFFREFL, nd.rdiff);
1822 >      diffPhotonScatter(nd.pnorm, &rayOut);
1823 >   }
1824 >  
1825 >   else if ((xi -= ptDiff) <= 0) {
1826 >      /* Diffuse transmission (extra component in material def) */
1827 >      flipsurface(rayIn);
1828 >      photonRay(rayIn, &rayOut, PMAP_DIFFTRANS, nd.tdiff);
1829 >      diffPhotonScatter(nd.pnorm, &rayOut);      
1830 >   }
1831 >  
1832 >   else {   /* Sample SDF */
1833 >      if ((xi -= prDiffSD) <= 0) {
1834 >         /* Diffuse SDF reflection (constant component) */
1835 >         if ((err = SDsampBSDF(&bsdfVal, nd.vray, xi2,
1836 >                               SDsampDf | SDsampR, nd.sd)))
1837 >            objerror(mat, USER, transSDError(err));
1838          
1839 <         if (!cdarr [i])
1840 <            cdarr [i] = &SDemptyCD;
1841 <         else bsdfVal.cieY += cdarr [i] -> cTotal;
1839 >         /* Apply pattern to spectral component */
1840 >         ccy2rgb(&bsdfVal.spec, bsdfVal.cieY, bsdfRGB);
1841 >         multcolor(bsdfRGB, rayIn -> pcol);
1842 >         photonRay(rayIn, &rayOut, PMAP_DIFFREFL, bsdfRGB);
1843        }
1560      
1561      if (bsdfVal.cieY <= FTINY) {
1562         /* Don't bother sampling, just absorb photon */
1563         if (cdarr)
1564            free(cdarr);
1565         return 0;
1566      }      
1567      
1568      /* Insert direct and indirect photon hits if diffuse component */
1569      if (rhoDiff > FTINY || nd.sd -> tLamb.cieY > FTINY)
1570         addPhotons(rayIn);    
1571        
1572      xi = pmapRandom(rouletteState);
1573      
1574      if ((xi -= rhoDiff) <= 0) {
1575         /* Diffuse reflection */
1576         photonRay(rayIn, &rayOut, PMAP_DIFFREFL, nd.rdiff);
1577         diffPhotonScatter(nd.pnorm, &rayOut);
1578      }
1579      else if ((xi -= nd.sd -> tLamb.cieY) <= 0) {
1580         /* Diffuse transmission */
1581         flipsurface(rayIn);
1582         photonRay(rayIn, &rayOut, PMAP_DIFFTRANS, nd.tdiff);
1583         bsdfVal.spec = nd.sd -> tLamb.spec;
1584         diffPhotonScatter(nd.pnorm, &rayOut);
1585      }
1586      else {
1587         int rayOutType;
1588         COLOR bsdfRGB;
1589            
1590         /* Non-diffuse CDF inversion (?) */
1591         for (i = 0; i < n && (xi -= cdarr [i] -> cTotal) > 0; i++);
1592        
1593         if (i >= n) {
1594            /* Absorbed -- photon went Deer Hunter */
1595            if (cdarr)
1596               free(cdarr);
1597            return 0;
1598         }
1844  
1845 <         if (i < nr) {
1846 <            /* Non-diffuse reflection */
1847 <            sdc = &rdf -> comp [i];
1848 <            rayOutType = PMAP_SPECREFL;
1849 <         }
1605 <         else {
1606 <            /* Non-diffuse transmission */
1607 <            sdc = &tdf -> comp [i - nr];
1608 <            rayOutType = PMAP_SPECTRANS;
1609 <         }
1845 >      else if ((xi -= ptDiffSD) <= 0) {
1846 >         /* Diffuse SDF transmission (constant component) */
1847 >         if ((err = SDsampBSDF(&bsdfVal, nd.vray, xi2,
1848 >                               SDsampDf | SDsampT, nd.sd)))
1849 >            objerror(mat, USER, transSDError(err));
1850          
1851 <         /* Generate non-diff sample dir */
1612 <         VCOPY(rayOut.rdir, nd.vray);
1613 <         err = (*sdc -> func -> sampCDist)
1614 <               (rayOut.rdir, pmapRandom(scatterState), cdarr [i]);              
1615 <         if (err)
1616 <            objerror(mat, USER, transSDError(SDEinternal));
1617 <
1618 <         /* Get colour */
1619 <         j = (*sdc -> func -> getBSDFs)(coef, rayOut.rdir, nd.vray, sdc);
1620 <        
1621 <         if (j <= 0) {
1622 <            sprintf(SDerrorDetail, "BSDF \"%s\" sampling value error",
1623 <                    nd.sd -> name);
1624 <            objerror(mat, USER, transSDError(SDEinternal));
1625 <         }
1626 <        
1627 <         bsdfVal.spec = sdc -> cspec [0];
1628 <         rhoDiff = coef [0];
1629 <        
1630 <         while (--j) {
1631 <            c_cmix(&bsdfVal.spec, rhoDiff, &bsdfVal.spec, coef [j],
1632 <                   &sdc -> cspec [j]);
1633 <            rhoDiff += coef [j];
1634 <         }
1635 <        
1636 <         /* ? */
1637 <         c_ccvt(&bsdfVal.spec, C_CSXY + C_CSSPEC);
1851 >         /* Apply pattern to spectral component */
1852           ccy2rgb(&bsdfVal.spec, bsdfVal.cieY, bsdfRGB);
1853 <        
1854 <         /* Xform outgoing dir to world coords */
1855 <         if ((err = SDmapDir(rayOut.rdir, nd.fromloc, rayOut.rdir))) {
1853 >         multcolor(bsdfRGB, rayIn -> pcol);
1854 >         addcolor(bsdfRGB, nd.tdiff);      
1855 >         flipsurface(rayIn);  /* Necessary? */
1856 >         photonRay(rayIn, &rayOut, PMAP_DIFFTRANS, bsdfRGB);
1857 >      }
1858 >
1859 >      else if ((xi -= prSpecSD) <= 0) {
1860 >         /* Non-diffuse ("specular") SDF reflection */
1861 >         if ((err = SDsampBSDF(&bsdfVal, nd.vray, xi2,
1862 >                               SDsampSp | SDsampR, nd.sd)))
1863              objerror(mat, USER, transSDError(err));
1643            return 0;
1644         }
1864          
1865 <         photonRay(rayIn, &rayOut, rayOutType, bsdfRGB);
1865 >         ccy2rgb(&bsdfVal.spec, bsdfVal.cieY, bsdfRGB);
1866 >         photonRay(rayIn, &rayOut, PMAP_SPECREFL, bsdfRGB);
1867        }
1868        
1869 <      if (cdarr)
1870 <         free(cdarr);
1869 >      else {
1870 >         /* Non-diffuse ("specular") SDF transmission */
1871 >         if ((err = SDsampBSDF(&bsdfVal, nd.vray, xi2,
1872 >                               SDsampSp | SDsampT, nd.sd)))
1873 >            objerror(mat, USER, transSDError(err));
1874 >
1875 >         /* Apply pattern to spectral component */
1876 >         ccy2rgb(&bsdfVal.spec, bsdfVal.cieY, bsdfRGB);
1877 >         multcolor(bsdfRGB, rayIn -> pcol);
1878 >         flipsurface(rayIn);  /* Necessary? */
1879 >         photonRay(rayIn, &rayOut, PMAP_SPECTRANS, bsdfRGB);
1880 >      }      
1881 >      
1882 >      /* Xform outgoing dir to world coords */
1883 >      if ((err = SDmapDir(rayOut.rdir, nd.fromloc, nd.vray))) {
1884 >         objerror(mat, USER, transSDError(err));
1885 >         return 0;
1886 >      }
1887     }
1888 <                        
1889 <   /* Clean up BSDF */
1888 >      
1889 >   /* Clean up */
1890     SDfreeCache(nd.sd);
1891  
1892     tracePhoton(&rayOut);
1893     return 0;
1894   }
1895 + #endif
1896  
1897  
1898  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines