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

Comparing ray/src/rt/ambient.c (file contents):
Revision 2.107 by greg, Sat Feb 16 00:09:53 2019 UTC vs.
Revision 2.108 by greg, Tue May 14 17:39:10 2019 UTC

# Line 78 | Line 78 | static long  lastpos = -1;             /* last flush position */
78  
79   #define  newambval()    (AMBVAL *)malloc(sizeof(AMBVAL))
80  
81 + #define  tfunc(lwr, x, upr)     (((x)-(lwr))/((upr)-(lwr)))
82 +
83   static void initambfile(int creat);
84   static void avsave(AMBVAL *av);
85   static AMBVAL *avstore(AMBVAL  *aval);
# Line 94 | Line 96 | static int aposcmp(const void *avp1, const void *avp2)
96   static int avlmemi(AMBVAL *avaddr);
97   static void sortambvals(int always);
98  
99 + static int      plugaleak(RAY *r, AMBVAL *ap, FVECT anorm, double ang);
100 + static double   sumambient(COLOR acol, RAY *r, FVECT rn, int al,
101 +                                AMBTREE *at, FVECT c0, double s);
102 + static int      makeambient(COLOR acol, RAY *r, FVECT rn, int al);
103 + static int      extambient(COLOR cr, AMBVAL *ap, FVECT pv, FVECT nv,
104 +                                FVECT uvw[3]);
105 +
106   #ifdef  F_SETLKW
107   static void aflock(int  typ);
108   #endif
# Line 255 | Line 264 | ambnotify(                     /* record new modifier */
264                  }
265   }
266  
258 /************ THE FOLLOWING ROUTINES DIFFER BETWEEN NEW & OLD ***************/
267  
260 #ifndef OLDAMB
261
262 #define tfunc(lwr, x, upr)      (((x)-(lwr))/((upr)-(lwr)))
263
264 static int      plugaleak(RAY *r, AMBVAL *ap, FVECT anorm, double ang);
265 static double   sumambient(COLOR acol, RAY *r, FVECT rn, int al,
266                                AMBTREE *at, FVECT c0, double s);
267 static int      makeambient(COLOR acol, RAY *r, FVECT rn, int al);
268 static int      extambient(COLOR cr, AMBVAL *ap, FVECT pv, FVECT nv,
269                                FVECT uvw[3]);
270
268   void
269   multambient(            /* compute ambient component & multiply by coef. */
270          COLOR  aval,
# Line 655 | Line 652 | avinsert(                              /* insert ambient value in our tree */
652          at->alist = avh.next;
653   }
654  
658
659 #else /* ! NEWAMB */
660
661 static double   sumambient(COLOR acol, RAY *r, FVECT rn, int al,
662                                AMBTREE *at, FVECT c0, double s);
663 static double   makeambient(COLOR acol, RAY *r, FVECT rn, int al);
664 static void     extambient(COLOR cr, AMBVAL *ap, FVECT pv, FVECT nv);
665
666
667 void
668 multambient(            /* compute ambient component & multiply by coef. */
669        COLOR  aval,
670        RAY  *r,
671        FVECT  nrm
672 )
673 {
674        static int  rdepth = 0;                 /* ambient recursion */
675        COLOR   acol, caustic;
676        double  d, l;
677
678        /* PMAP: Factor in ambient from global photon map (if enabled) and return
679         * as all ambient components accounted for */
680        if (ambPmap(aval, r, rdepth))
681                return;
682
683        /* PMAP: Otherwise factor in ambient from caustic photon map
684         * (ambPmapCaustic() returns zero if caustic photons disabled) and
685         * continue with RADIANCE ambient calculation */
686        copycolor(caustic, aval);
687        ambPmapCaustic(caustic, r, rdepth);
688        
689        if (ambdiv <= 0)                        /* no ambient calculation */
690                goto dumbamb;
691                                                /* check number of bounces */
692        if (rdepth >= ambounce)
693                goto dumbamb;
694                                                /* check ambient list */
695        if (ambincl != -1 && r->ro != NULL &&
696                        ambincl != inset(ambset, r->ro->omod))
697                goto dumbamb;
698
699        if (ambacc <= FTINY) {                  /* no ambient storage */
700                copycolor(acol, aval);
701                rdepth++;
702                d = doambient(acol, r, r->rweight, NULL, NULL);
703                rdepth--;
704                if (d <= FTINY)
705                        goto dumbamb;
706                copycolor(aval, acol);          
707        
708           /* PMAP: add in caustic */
709                addcolor(aval, caustic);        
710                return;
711        }
712
713        if (tracktime)                          /* sort to minimize thrashing */
714                sortambvals(0);
715                                                /* interpolate ambient value */
716        setcolor(acol, 0.0, 0.0, 0.0);
717        d = sumambient(acol, r, nrm, rdepth,
718                        &atrunk, thescene.cuorg, thescene.cusize);
719                        
720        if (d > FTINY) {
721                d = 1.0/d;
722                scalecolor(acol, d);
723                multcolor(aval, acol);
724                
725                /* PMAP: add in caustic */
726                addcolor(aval, caustic);        
727                return;
728        }
729        
730        rdepth++;                               /* need to cache new value */
731        d = makeambient(acol, r, nrm, rdepth-1);
732        rdepth--;
733        
734        if (d > FTINY) {
735                multcolor(aval, acol);          /* got new value */
736
737                /* PMAP: add in caustic */
738                addcolor(aval, caustic);                        
739                return;
740        }
741        
742 dumbamb:                                        /* return global value */
743        if ((ambvwt <= 0) | (navsum == 0)) {
744                multcolor(aval, ambval);
745
746                /* PMAP: add in caustic */
747                addcolor(aval, caustic);        
748                return;
749        }
750        
751        l = bright(ambval);                     /* average in computations */
752        if (l > FTINY) {
753                d = (log(l)*(double)ambvwt + avsum) /
754                                (double)(ambvwt + navsum);
755                d = exp(d) / l;
756                scalecolor(aval, d);
757                multcolor(aval, ambval);        /* apply color of ambval */
758        } else {
759                d = exp( avsum / (double)navsum );
760                scalecolor(aval, d);            /* neutral color */
761        }
762 }
763
764
765 static double
766 sumambient(     /* get interpolated ambient value */
767        COLOR  acol,
768        RAY  *r,
769        FVECT  rn,
770        int  al,
771        AMBTREE  *at,
772        FVECT  c0,
773        double  s
774 )
775 {
776        double  d, e1, e2, wt, wsum;
777        COLOR  ct;
778        FVECT  ck0;
779        int  i;
780        int  j;
781        AMBVAL   *av;
782
783        wsum = 0.0;
784                                        /* do this node */
785        for (av = at->alist; av != NULL; av = av->next) {
786                double  rn_dot = -2.0;
787                if (tracktime)
788                        av->latick = ambclock;
789                /*
790                 *  Ambient level test.
791                 */
792                if (av->lvl > al ||     /* list sorted, so this works */
793                                (av->lvl == al) & (av->weight < 0.9*r->rweight))
794                        break;
795                /*
796                 *  Ambient radius test.
797                 */
798                VSUB(ck0, av->pos, r->rop);
799                e1 = DOT(ck0, ck0) / (av->rad * av->rad);
800                if (e1 > ambacc*ambacc*1.21)
801                        continue;
802                /*
803                 *  Direction test using closest normal.
804                 */
805                d = DOT(av->dir, r->ron);
806                if (rn != r->ron) {
807                        rn_dot = DOT(av->dir, rn);
808                        if (rn_dot > 1.0-FTINY)
809                                rn_dot = 1.0-FTINY;
810                        if (rn_dot >= d-FTINY) {
811                                d = rn_dot;
812                                rn_dot = -2.0;
813                        }
814                }
815                e2 = (1.0 - d) * r->rweight;
816                if (e2 < 0.0)
817                        e2 = 0.0;
818                else if (e1 + e2 > ambacc*ambacc*1.21)
819                        continue;
820                /*
821                 *  Ray behind test.
822                 */
823                d = 0.0;
824                for (j = 0; j < 3; j++)
825                        d += (r->rop[j] - av->pos[j]) *
826                                        (av->dir[j] + r->ron[j]);
827                if (d*0.5 < -minarad*ambacc-.001)
828                        continue;
829                /*
830                 *  Jittering final test reduces image artifacts.
831                 */
832                e1 = sqrt(e1);
833                e2 = sqrt(e2);
834                wt = e1 + e2;
835                if (wt > ambacc*(.9+.2*urand(9015+samplendx)))
836                        continue;
837                /*
838                 *  Recompute directional error using perturbed normal
839                 */
840                if (rn_dot > 0.0) {
841                        e2 = sqrt((1.0 - rn_dot)*r->rweight);
842                        wt = e1 + e2;
843                }
844                if (wt <= 1e-3)
845                        wt = 1e3;
846                else
847                        wt = 1.0 / wt;
848                wsum += wt;
849                extambient(ct, av, r->rop, rn);
850                scalecolor(ct, wt);
851                addcolor(acol, ct);
852        }
853        if (at->kid == NULL)
854                return(wsum);
855                                        /* do children */
856        s *= 0.5;
857        for (i = 0; i < 8; i++) {
858                for (j = 0; j < 3; j++) {
859                        ck0[j] = c0[j];
860                        if (1<<j & i)
861                                ck0[j] += s;
862                        if (r->rop[j] < ck0[j] - OCTSCALE*s)
863                                break;
864                        if (r->rop[j] > ck0[j] + (1.0+OCTSCALE)*s)
865                                break;
866                }
867                if (j == 3)
868                        wsum += sumambient(acol, r, rn, al,
869                                                at->kid+i, ck0, s);
870        }
871        return(wsum);
872 }
873
874
875 static double
876 makeambient(            /* make a new ambient value for storage */
877        COLOR  acol,
878        RAY  *r,
879        FVECT  rn,
880        int  al
881 )
882 {
883        AMBVAL  amb;
884        FVECT   gp, gd;
885        int     i;
886
887        amb.weight = 1.0;                       /* compute weight */
888        for (i = al; i-- > 0; )
889                amb.weight *= AVGREFL;
890        if (r->rweight < 0.1*amb.weight)        /* heuristic override */
891                amb.weight = 1.25*r->rweight;
892        setcolor(acol, AVGREFL, AVGREFL, AVGREFL);
893                                                /* compute ambient */
894        amb.rad = doambient(acol, r, amb.weight, gp, gd);
895        if (amb.rad <= FTINY) {
896                setcolor(acol, 0.0, 0.0, 0.0);
897                return(0.0);
898        }
899        scalecolor(acol, 1./AVGREFL);           /* undo assumed reflectance */
900                                                /* store value */
901        VCOPY(amb.pos, r->rop);
902        VCOPY(amb.dir, r->ron);
903        amb.lvl = al;
904        copycolor(amb.val, acol);
905        VCOPY(amb.gpos, gp);
906        VCOPY(amb.gdir, gd);
907                                                /* insert into tree */
908        avsave(&amb);                           /* and save to file */
909        if (rn != r->ron)
910                extambient(acol, &amb, r->rop, rn);     /* texture */
911        return(amb.rad);
912 }
913
914
915 static void
916 extambient(             /* extrapolate value at pv, nv */
917        COLOR  cr,
918        AMBVAL   *ap,
919        FVECT  pv,
920        FVECT  nv
921 )
922 {
923        FVECT  v1;
924        int  i;
925        double  d;
926
927        d = 1.0;                        /* zeroeth order */
928                                        /* gradient due to translation */
929        for (i = 0; i < 3; i++)
930                d += ap->gpos[i]*(pv[i]-ap->pos[i]);
931                                        /* gradient due to rotation */
932        VCROSS(v1, ap->dir, nv);
933        d += DOT(ap->gdir, v1);
934        if (d <= 0.0) {
935                setcolor(cr, 0.0, 0.0, 0.0);
936                return;
937        }
938        copycolor(cr, ap->val);
939        scalecolor(cr, d);
940 }
941
942
943 static void
944 avinsert(                               /* insert ambient value in our tree */
945        AMBVAL *av
946 )
947 {
948        AMBTREE  *at;
949        AMBVAL  *ap;
950        AMBVAL  avh;
951        FVECT  ck0;
952        double  s;
953        int  branch;
954        int  i;
955
956        if (av->rad <= FTINY)
957                error(CONSISTENCY, "zero ambient radius in avinsert");
958        at = &atrunk;
959        VCOPY(ck0, thescene.cuorg);
960        s = thescene.cusize;
961        while (s*(OCTSCALE/2) > av->rad*ambacc) {
962                if (at->kid == NULL)
963                        if ((at->kid = newambtree()) == NULL)
964                                error(SYSTEM, "out of memory in avinsert");
965                s *= 0.5;
966                branch = 0;
967                for (i = 0; i < 3; i++)
968                        if (av->pos[i] > ck0[i] + s) {
969                                ck0[i] += s;
970                                branch |= 1 << i;
971                        }
972                at = at->kid + branch;
973        }
974        avh.next = at->alist;           /* order by increasing level */
975        for (ap = &avh; ap->next != NULL; ap = ap->next)
976                if ( ap->next->lvl > av->lvl ||
977                                (ap->next->lvl == av->lvl) &
978                                (ap->next->weight <= av->weight) )
979                        break;
980        av->next = ap->next;
981        ap->next = (AMBVAL*)av;
982        at->alist = avh.next;
983 }
984
985 #endif  /* ! NEWAMB */
986
987 /************* FOLLOWING ROUTINES SAME FOR NEW & OLD METHODS ***************/
655  
656   static void
657   initambfile(            /* initialize ambient file */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines