ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_brdf.c
Revision: 1.4
Committed: Sat Dec 15 15:03:44 1990 UTC (33 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +13 -7 lines
Log Message:
changed handling of matrix transformations with new MAT4 & XF types
dynamic allocation of ray transformations with newrayxf()
added missing light source vector transformation to m_brdf.c

File Contents

# Content
1 /* Copyright (c) 1990 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Shading for materials with arbitrary BRDF's
9 */
10
11 #include "ray.h"
12
13 #include "data.h"
14
15 #include "otypes.h"
16
17 /*
18 * Arguments to this material include the color and specularity.
19 * String arguments include the reflection function and files.
20 * The BRDF is currently used just for the specular component to light
21 * sources. Reflectance values or data coordinates are functions
22 * of the direction to the light source.
23 * We orient the surface towards the incoming ray, so a single
24 * surface can be used to represent an infinitely thin object.
25 *
26 * Arguments for MAT_PFUNC and MAT_MFUNC are:
27 * 2+ func funcfile transform
28 * 0
29 * 4+ red grn blu specularity A5 ..
30 *
31 * Arguments for MAT_PDATA and MAT_MDATA are:
32 * 4+ func datafile funcfile v0 .. transform
33 * 0
34 * 4+ red grn blu specularity A5 ..
35 */
36
37 extern double funvalue(), varvalue();
38
39 typedef struct {
40 OBJREC *mp; /* material pointer */
41 RAY *pr; /* intersected ray */
42 DATARRAY *dp; /* data array for PDATA or MDATA */
43 COLOR mcolor; /* color of this material */
44 COLOR scolor; /* color of specular component */
45 double rspec; /* specular reflection */
46 double rdiff; /* diffuse reflection */
47 FVECT pnorm; /* perturbed surface normal */
48 double pdot; /* perturbed dot product */
49 } BRDFDAT; /* BRDF material data */
50
51
52 dirbrdf(cval, np, ldir, omega) /* compute source contribution */
53 COLOR cval; /* returned coefficient */
54 register BRDFDAT *np; /* material data */
55 FVECT ldir; /* light source direction */
56 double omega; /* light source size */
57 {
58 extern XF funcxf;
59 double ldot;
60 double dtmp;
61 COLOR ctmp;
62 FVECT ldx;
63 double pt[MAXDIM];
64 register int i;
65
66 setcolor(cval, 0.0, 0.0, 0.0);
67
68 ldot = DOT(np->pnorm, ldir);
69
70 if (ldot < 0.0)
71 return; /* wrong side */
72
73 if (np->rdiff > FTINY) {
74 /*
75 * Compute and add diffuse reflected component to returned
76 * color. The diffuse reflected component will always be
77 * modified by the color of the material.
78 */
79 copycolor(ctmp, np->mcolor);
80 dtmp = ldot * omega * np->rdiff / PI;
81 scalecolor(ctmp, dtmp);
82 addcolor(cval, ctmp);
83 }
84 if (np->rspec > FTINY) {
85 /*
86 * Compute specular component.
87 */
88 setfunc(np->mp, np->pr);
89 /* transform light vector */
90 multv3(ldx, ldir, funcxf.xfm);
91 for (i = 0; i < 3; i++)
92 ldx[i] /= funcxf.sca;
93 /* evaluate BRDF */
94 errno = 0;
95 if (np->dp == NULL)
96 dtmp = funvalue(np->mp->oargs.sarg[0], 3, ldx);
97 else {
98 for (i = 0; i < np->dp->nd; i++)
99 pt[i] = funvalue(np->mp->oargs.sarg[3+i],
100 3, ldx);
101 dtmp = datavalue(np->dp, pt);
102 dtmp = funvalue(np->mp->oargs.sarg[0], 1, &dtmp);
103 }
104 if (errno)
105 goto computerr;
106 if (dtmp > FTINY) {
107 copycolor(ctmp, np->scolor);
108 dtmp *= ldot * omega;
109 scalecolor(ctmp, dtmp);
110 addcolor(cval, ctmp);
111 }
112 }
113 return;
114 computerr:
115 objerror(np->mp, WARNING, "compute error");
116 return;
117 }
118
119
120 m_brdf(m, r) /* color a ray which hit a BRDF material */
121 register OBJREC *m;
122 register RAY *r;
123 {
124 BRDFDAT nd;
125 COLOR ctmp;
126 register int i;
127
128 if (m->oargs.nsargs < 2 || m->oargs.nfargs < 4)
129 objerror(m, USER, "bad # arguments");
130 /* easy shadow test */
131 if (r->crtype & SHADOW)
132 return;
133 nd.mp = m;
134 nd.pr = r;
135 /* load auxiliary files */
136 if (m->otype == MAT_PDATA || m->otype == MAT_MDATA) {
137 nd.dp = getdata(m->oargs.sarg[1]);
138 for (i = 3; i < m->oargs.nsargs; i++)
139 if (m->oargs.sarg[i][0] == '-')
140 break;
141 if (i-3 != nd.dp->nd)
142 objerror(m, USER, "dimension error");
143 if (!fundefined(m->oargs.sarg[3]))
144 loadfunc(m->oargs.sarg[2]);
145 } else {
146 nd.dp = NULL;
147 if (!fundefined(m->oargs.sarg[0]))
148 loadfunc(m->oargs.sarg[1]);
149 }
150 /* get material color */
151 setcolor(nd.mcolor, m->oargs.farg[0],
152 m->oargs.farg[1],
153 m->oargs.farg[2]);
154 /* get roughness */
155 if (r->rod < 0.0)
156 flipsurface(r);
157 /* get modifiers */
158 raytexture(r, m->omod);
159 nd.pdot = raynormal(nd.pnorm, r); /* perturb normal */
160 multcolor(nd.mcolor, r->pcol); /* modify material color */
161 r->rt = r->rot; /* default ray length */
162 /* get specular component */
163 nd.rspec = m->oargs.farg[3];
164
165 if (nd.rspec > FTINY) { /* has specular component */
166 /* compute specular color */
167 if (m->otype == MAT_MFUNC || m->otype == MAT_MDATA)
168 copycolor(nd.scolor, nd.mcolor);
169 else
170 setcolor(nd.scolor, 1.0, 1.0, 1.0);
171 scalecolor(nd.scolor, nd.rspec);
172 }
173 /* diffuse reflection */
174 nd.rdiff = 1.0 - nd.rspec;
175 /* compute ambient */
176 if (nd.rdiff > FTINY) {
177 ambient(ctmp, r);
178 multcolor(ctmp, nd.mcolor); /* modified by material color */
179 addcolor(r->rcol, ctmp); /* add to returned color */
180 }
181 /* add direct component */
182 direct(r, dirbrdf, &nd);
183 }