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

Comparing ray/src/rt/ambcomp.c (file contents):
Revision 2.25 by greg, Fri Apr 11 20:31:37 2014 UTC vs.
Revision 2.26 by greg, Wed Apr 16 20:32:00 2014 UTC

# Line 15 | Line 15 | static const char      RCSid[] = "$Id$";
15  
16   #ifdef NEWAMB
17  
18 + extern void             SDsquare2disk(double ds[2], double seedx, double seedy);
19 +
20 + typedef struct {
21 +        RAY     *rp;            /* originating ray sample */
22 +        FVECT   ux, uy;         /* tangent axis directions */
23 +        int     ns;             /* number of samples per axis */
24 +        COLOR   acoef;          /* division contribution coefficient */
25 +        struct s_ambsamp {
26 +                COLOR   v;              /* hemisphere sample value */
27 +                float   p[3];           /* intersection point */
28 +        } sa[1];                /* sample array (extends struct) */
29 + }  AMBHEMI;             /* ambient sample hemisphere */
30 +
31 + #define ambsamp(h,i,j)  (h)->sa[(i)*(h)->ns + (j)]
32 +
33 +
34 + static AMBHEMI *
35 + inithemi(                       /* initialize sampling hemisphere */
36 +        COLOR   ac,
37 +        RAY     *r,
38 +        double  wt
39 + )
40 + {
41 +        AMBHEMI *hp;
42 +        double  d;
43 +        int     n, i;
44 +                                        /* set number of divisions */
45 +        if (ambacc <= FTINY &&
46 +                        wt > (d = 0.8*intens(ac)*r->rweight/(ambdiv*minweight)))
47 +                wt = d;                 /* avoid ray termination */
48 +        n = sqrt(ambdiv * wt) + 0.5;
49 +        i = 1 + 4*(ambacc > FTINY);     /* minimum number of samples */
50 +        if (n < i)
51 +                n = i;
52 +                                        /* allocate sampling array */
53 +        hp = (AMBHEMI *)malloc(sizeof(AMBHEMI) +
54 +                                sizeof(struct s_ambsamp)*(n*n - 1));
55 +        if (hp == NULL)
56 +                return(NULL);
57 +        hp->rp = r;
58 +        hp->ns = n;
59 +                                        /* assign coefficient */
60 +        copycolor(hp->acoef, ac);
61 +        d = 1.0/(n*n);
62 +        scalecolor(hp->acoef, d);
63 +                                        /* make tangent axes */
64 +        hp->uy[0] = hp->uy[1] = hp->uy[2] = 0.0;
65 +        for (i = 0; i < 3; i++)
66 +                if (r->rn[i] < 0.6 && r->rn[i] > -0.6)
67 +                        break;
68 +        if (i >= 3)
69 +                error(CONSISTENCY, "bad ray direction in inithemi()");
70 +        hp->uy[i] = 1.0;
71 +        VCROSS(hp->ux, hp->uy, r->rn);
72 +        normalize(hp->ux);
73 +        VCROSS(hp->uy, r->rn, hp->ux);
74 +                                        /* we're ready to sample */
75 +        return(hp);
76 + }
77 +
78 +
79 + static int
80 + ambsample(                              /* sample an ambient direction */
81 +        AMBHEMI *hp,
82 +        int     i,
83 +        int     j,
84 + )
85 + {
86 +        struct s_ambsamp        *ap = &ambsamp(hp,i,j);
87 +        RAY                     ar;
88 +        int                     hlist[3];
89 +        double                  spt[2], dz;
90 +        int                     ii;
91 +                                        /* ambient coefficient for weight */
92 +        if (ambacc > FTINY)
93 +                setcolor(ar.rcoef, AVGREFL, AVGREFL, AVGREFL);
94 +        else
95 +                copycolor(ar.rcoef, hp->acoef);
96 +        if (rayorigin(&ar, AMBIENT, hp->rp, ar.rcoef) < 0) {
97 +                setcolor(ap->v, 0., 0., 0.);
98 +                ap->r = 0.;
99 +                return(0);              /* no sample taken */
100 +        }
101 +        if (ambacc > FTINY) {
102 +                multcolor(ar.rcoef, hp->acoef);
103 +                scalecolor(ar.rcoef, 1./AVGREFL);
104 +        }
105 +                                        /* generate hemispherical sample */
106 +        SDsquare2disk(spt, (i+frandom())/hp->ns, (j+frandom())/hp->ns);
107 +        zd = sqrt(1. - spt[0]*spt[0] - spt[1]*spt[1]);
108 +        for (ii = 3; ii--; )
109 +                ar.rdir[ii] =   spt[0]*hp->ux[ii] +
110 +                                spt[1]*hp->uy[ii] +
111 +                                zd*hp->rp->ron[ii];
112 +        checknorm(ar.rdir);
113 +        dimlist[ndims++] = i*hp->ns + j + 90171;
114 +        rayvalue(&ar);                  /* evaluate ray */
115 +        ndims--;
116 +        multcolor(ar.rcol, ar.rcoef);   /* apply coefficient */
117 +        copycolor(ap->v, ar.rcol);
118 +        if (ar.rt > 20.0*maxarad)       /* limit vertex distance */
119 +                ar.rt = 20.0*maxarad;
120 +        VSUM(ap->p, ar.rorg, ar.rdir, ar.rt);
121 +        return(1);
122 + }
123 +
124 +
125 + static void
126 + ambHessian(                             /* anisotropic radii & pos. gradient */
127 +        AMBHEMI *hp,
128 +        FVECT   uv[2],                  /* returned */
129 +        float   ra[2],                  /* returned */
130 +        float   pg[2]                   /* returned */
131 + )
132 + {
133 +        if (ra != NULL) {               /* compute Hessian-derived radii */
134 +        } else {                        /* else copy original tangent axes */
135 +                VCOPY(uv[0], hp->ux);
136 +                VCOPY(uv[1], hp->uy);
137 +        }
138 +        if (pg == NULL)                 /* no position gradient requested? */
139 +                return;
140 + }
141 +
142 + int
143 + doambient(                              /* compute ambient component */
144 +        COLOR   rcol,                   /* input/output color */
145 +        RAY     *r,
146 +        double  wt,
147 +        FVECT   uv[2],                  /* returned */
148 +        float   ra[2],                  /* returned */
149 +        float   pg[2],                  /* returned */
150 +        float   dg[2]                   /* returned */
151 + )
152 + {
153 +        int                     cnt = 0;
154 +        FVECT                   my_uv[2];
155 +        AMBHEMI                 *hp;
156 +        double                  d, acol[3];
157 +        struct s_ambsamp        *ap;
158 +        int                     i, j;
159 +                                        /* initialize */
160 +        if ((hp = inithemi(rcol, r, wt)) == NULL)
161 +                return(0);
162 +        if (uv != NULL)
163 +                memset(uv, 0, sizeof(FVECT)*2);
164 +        if (ra != NULL)
165 +                ra[0] = ra[1] = 0.0;
166 +        if (pg != NULL)
167 +                pg[0] = pg[1] = 0.0;
168 +        if (dg != NULL)
169 +                dg[0] = dg[1] = 0.0;
170 +                                        /* sample the hemisphere */
171 +        acol[0] = acol[1] = acol[2] = 0.0;
172 +        for (i = hemi.ns; i--; )
173 +                for (j = hemi.ns; j--; )
174 +                        if (ambsample(hp, i, j)) {
175 +                                ap = &ambsamp(hp,i,j);
176 +                                addcolor(acol, ap->v);
177 +                                ++cnt;
178 +                        }
179 +        if (!cnt) {
180 +                setcolor(rcol, 0.0, 0.0, 0.0);
181 +                free(hp);
182 +                return(0);              /* no valid samples */
183 +        }
184 +        d = 1.0 / cnt;                  /* final indirect irradiance/PI */
185 +        acol[0] *= d; acol[1] *= d; acol[2] *= d;
186 +        copycolor(rcol, acol);
187 +        if (cnt < hp->ns*hp->ns ||      /* incomplete sampling? */
188 +                        (ra == NULL) & (pg == NULL) & (dg == NULL)) {
189 +                free(hp);
190 +                return(-1);             /* no radius or gradient calc. */
191 +        }
192 +        d = 0.01 * bright(rcol);        /* add in 1% before Hessian comp. */
193 +        if (d < FTINY) d = FTINY;
194 +        ap = hp->sa;                    /* using Y channel from here on... */
195 +        for (i = hp->ns*hp->ns; i--; ap++)
196 +                colval(ap->v,CIEY) = bright(ap->v) + d;
197 +
198 +        if (uv == NULL)                 /* make sure we have axis pointers */
199 +                uv = my_uv;
200 +                                        /* compute radii & pos. gradient */
201 +        ambHessian(hp, uv, ra, pg);
202 +        if (dg != NULL)                 /* compute direction gradient */
203 +                ambdirgrad(hp, uv, dg);
204 +        if (ra != NULL) {               /* adjust/clamp radii */
205 +                d = pow(wt, -0.25);
206 +                if ((ra[0] *= d) > maxarad)
207 +                        ra[0] = maxarad;
208 +                if ((ra[1] *= d) > 2.0*ra[0])
209 +                        ra[1] = 2.0*ra[0];
210 +        }
211 +        free(hp);                       /* clean up and return */
212 +        return(1);
213 + }
214 +
215 +
216   #else /* ! NEWAMB */
217  
218  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines