ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/bsdf.h
Revision: 2.16
Committed: Sun Aug 21 22:38:12 2011 UTC (12 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R1
Changes since 2.15: +4 -4 lines
Log Message:
Minor improvements to direct specular sampling

File Contents

# Content
1 /* RCSid $Id: bsdf.h,v 2.15 2011/06/09 17:09:39 greg Exp $ */
2 /*
3 * bsdf.h
4 *
5 * Declarations for bidirectional scattering distribution functions.
6 * Assumes <stdio.h> already included.
7 *
8 * A material is oriented in right-hand coordinate system with X-axis
9 * in the surface plane pointed to the right as seen from the front.
10 * This means the Y-axis is "up" and the Z-axis is the surface normal.
11 *
12 * Note that we reverse the identification of "front" and "back" from
13 * the conventions used in WINDOW 6. "Front" in our library points
14 * in the +Z direction, towards the interior of the space rather
15 * than the exterior.
16 *
17 * BSDF incident & exiting vectors are always oriented away from surface.
18 *
19 * Created by Greg Ward on 1/10/11.
20 *
21 */
22
23 #ifndef _BSDF_H_
24 #define _BSDF_H_
25
26 #include "fvect.h"
27 #include "ccolor.h"
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33 #ifdef _WIN32
34 #define strcasecmp stricmp
35 #endif
36
37 #define SDnameLn 128 /* maximum BSDF name length */
38 #define SDmaxCh 3 /* maximum # spectral channels */
39
40 /* Component flags for SDsampBSDF() and SDdirectHemi() */
41 #define SDsampR 0x1 /* include reflection */
42 #define SDsampT 0x2 /* include transmission */
43 #define SDsampS 0x3 /* include scattering (R+T) */
44 #define SDsampSp 0x4 /* include non-diffuse portion */
45 #define SDsampDf 0x8 /* include diffuse portion */
46 #define SDsampSpR 0x5 /* include non-diffuse reflection */
47 #define SDsampSpT 0x6 /* include non-diffuse transmission */
48 #define SDsampSpS 0x7 /* include non-diffuse scattering */
49 #define SDsampAll 0xF /* include everything */
50
51 /* Projected solid angle query flags for SDsizeBSDF() */
52 #define SDqueryVal 0x0 /* query single value */
53 #define SDqueryMin 0x1 /* query minimum proj. solid angle */
54 #define SDqueryMax 0x2 /* query maximum proj. solid angle */
55
56 /* Error codes: normal return, out of memory, file i/o, file format, bad argument,
57 bad data, unsupported feature, internal error, unknown error */
58 typedef enum {SDEnone=0, SDEmemory, SDEfile, SDEformat, SDEargument,
59 SDEdata, SDEsupport, SDEinternal, SDEunknown} SDError;
60
61 /* English ASCII strings corresponding to ennumerated errors */
62 extern const char *SDerrorEnglish[];
63
64 /* Additional information on last error (ASCII English) */
65 extern char SDerrorDetail[];
66
67 /* Holder for BSDF value and spectral color */
68 typedef struct {
69 double cieY; /* photopic BSDF (Y) value */
70 C_COLOR spec; /* spectral and (x,y) color */
71 } SDValue;
72
73 /* Cached, encoded, cumulative distribution for one incident (solid) angle */
74 #define SD_CDIST_BASE(styp) double cTotal; \
75 struct styp *next
76 typedef struct SDCDst_s {
77 SD_CDIST_BASE(SDCDst_s); /* base fields first */
78 /* ...encoded distribution extends struct */
79 } SDCDst;
80
81 /* Forward declaration of BSDF component */
82 typedef struct SDComp_s SDComponent;
83
84 /* Methods needed to handle BSDF components (nothing is optional) */
85 typedef const struct {
86 /* return non-diffuse BSDF */
87 int (*getBSDFs)(float coef[SDmaxCh], const FVECT outVec,
88 const FVECT inVec, SDComponent *sdc);
89 /* query non-diffuse PSA for vector */
90 SDError (*queryProjSA)(double *psa, const FVECT v1,
91 const RREAL *v2, int qflags,
92 SDComponent *sdc);
93 /* get cumulative distribution */
94 const SDCDst *(*getCDist)(const FVECT inVec, SDComponent *sdc);
95 /* sample cumulative distribution */
96 SDError (*sampCDist)(FVECT ioVec, double randX,
97 const SDCDst *cdp);
98 /* free a spectral BSDF component */
99 void (*freeSC)(void *dist);
100 } SDFunc;
101
102 /* Structure to hold a spectral BSDF component (typedef SDComponent above) */
103 struct SDComp_s {
104 C_COLOR cspec[SDmaxCh]; /* component spectral bases */
105 SDFunc *func; /* methods for this component */
106 void *dist; /* loaded distribution data */
107 SDCDst *cdList; /* cumulative distribution cache */
108 };
109
110 /* Container for non-diffuse BSDF components */
111 typedef struct {
112 double minProjSA; /* minimum projected solid angle */
113 double maxHemi; /* maximum directional hemispherical */
114 int ncomp; /* number of separate components */
115 SDComponent comp[1]; /* BSDF components (extends struct) */
116 } SDSpectralDF;
117
118 /* Loaded BSDF data */
119 typedef struct {
120 char name[SDnameLn]; /* BSDF name (usu. derived from file) */
121 char *mgf; /* geometric description (if any) */
122 float dim[3]; /* width, height, thickness (meters) */
123 SDValue rLambFront; /* diffuse front reflectance */
124 SDValue rLambBack; /* diffuse rear reflectance */
125 SDValue tLamb; /* diffuse transmission */
126 SDSpectralDF *rf, *rb, *tf; /* non-diffuse BSDF components */
127 } SDData;
128
129 /* List of loaded BSDFs */
130 extern struct SDCache_s {
131 SDData bsdf; /* BSDF data */
132 unsigned refcnt; /* how many callers are using us? */
133 struct SDCache_s /* next in cache list */
134 *next;
135 } *SDcacheList; /* Global BSDF cache */
136
137 /* BSDF cache retention policies */
138 #define SDretainNone 0 /* free unreferenced BSDF data */
139 #define SDretainBSDFs 1 /* keep loaded BSDFs in memory */
140 #define SDretainAll 2 /* also keep cumulative cache data */
141
142 extern int SDretainSet; /* =SDretainNone by default */
143
144 /*****************************************************************
145 * The following routines are less commonly used by applications.
146 */
147
148 #define SDisLoaded(sd) ((sd)->rLambFront.spec.flags != 0)
149
150 /* Report an error to the indicated stream (in English) */
151 extern SDError SDreportEnglish(SDError ec, FILE *fp);
152
153 /* Shorten file path to useable BSDF name, removing suffix */
154 extern void SDclipName(char res[SDnameLn], const char *fname);
155
156 /* Allocate new spectral distribution function */
157 extern SDSpectralDF *SDnewSpectralDF(int nc);
158
159 /* Free a spectral distribution function */
160 extern void SDfreeSpectralDF(SDSpectralDF *df);
161
162 /* Initialize an unused BSDF struct and assign name (calls SDclipName) */
163 extern void SDclearBSDF(SDData *sd, const char *fname);
164
165 /* Load a BSDF struct from the given file (keeps name unchanged) */
166 extern SDError SDloadFile(SDData *sd, const char *fname);
167
168 /* Free data associated with BSDF struct */
169 extern void SDfreeBSDF(SDData *sd);
170
171 /* Find writeable BSDF by name, or allocate new cache entry if absent */
172 extern SDData *SDgetCache(const char *bname);
173
174 /* Free cached cumulative distributions for BSDF component */
175 extern void SDfreeCumulativeCache(SDSpectralDF *df);
176
177 /* Sample an individual BSDF component */
178 extern SDError SDsampComponent(SDValue *sv, FVECT ioVec,
179 double randX, SDComponent *sdc);
180
181 /* Convert 1-dimensional random variable to N-dimensional */
182 extern void SDmultiSamp(double t[], int n, double randX);
183
184 /* Map a [0,1]^2 square to a unit radius disk */
185 void SDsquare2disk(double ds[2], double seedx, double seedy);
186
187 /* Map point on unit disk to a unit square in [0,1]^2 range */
188 void SDdisk2square(double sq[2], double diskx, double disky);
189
190 /*****************************************************************
191 * The calls below are the ones most applications require.
192 * All directions are assumed to be unit vectors.
193 */
194
195 /* Get BSDF from cache (or load and cache it on first call) */
196 /* Report any problems to stderr (in English), return NULL on failure */
197 extern const SDData *SDcacheFile(const char *fname);
198
199 /* Free a BSDF from our cache (clear all if sd==NULL) */
200 extern void SDfreeCache(const SDData *sd);
201
202 /* Query projected solid angle resolution for non-diffuse BSDF direction(s) */
203 extern SDError SDsizeBSDF(double *projSA, const FVECT v1,
204 const RREAL *v2, int qflags,
205 const SDData *sd);
206
207 /* Return BSDF for the given incident and scattered ray vectors */
208 extern SDError SDevalBSDF(SDValue *sv, const FVECT outVec,
209 const FVECT inVec, const SDData *sd);
210
211 /* Compute directional hemispherical scattering at given incident angle */
212 extern double SDdirectHemi(const FVECT inVec,
213 int sflags, const SDData *sd);
214
215 /* Sample BSDF direction based on the given random variable */
216 extern SDError SDsampBSDF(SDValue *sv, FVECT ioVec, double randX,
217 int sflags, const SDData *sd);
218
219 /*****************************************************************
220 * Vector math for getting between world and local BSDF coordinates.
221 * Directions may be passed unnormalized to these routines.
222 */
223
224 /* Compute World->BSDF transform from surface normal and BSDF up vector */
225 extern SDError SDcompXform(RREAL vMtx[3][3], const FVECT sNrm,
226 const FVECT uVec);
227
228 /* Compute inverse transform */
229 extern SDError SDinvXform(RREAL iMtx[3][3], RREAL vMtx[3][3]);
230
231 /* Transform and normalize direction (column) vector */
232 extern SDError SDmapDir(FVECT resVec, RREAL vMtx[3][3],
233 const FVECT inpVec);
234
235 /* Application-specific BSDF loading routine (not part of our library) */
236 extern SDData *loadBSDF(char *name);
237
238 /* Application-specific BSDF error translator (not part of our library) */
239 extern char *transSDError(SDError ec);
240
241 /*################################################################*/
242 /*######### DEPRECATED DEFINITIONS AWAITING PERMANENT REMOVAL #######*/
243 /*
244 * Header for BSDF i/o and access routines
245 */
246
247 #include "mat4.h"
248 /* up directions */
249 typedef enum {
250 UDzneg=-3,
251 UDyneg=-2,
252 UDxneg=-1,
253 UDunknown=0,
254 UDxpos=1,
255 UDypos=2,
256 UDzpos=3
257 } UpDir;
258 /* BSDF coordinate calculation routines */
259 /* vectors always point away from surface */
260
261 typedef int b_vecf2(FVECT v, int n, void *cd);
262 typedef int b_ndxf2(FVECT v, void *cd);
263 typedef double b_radf2(int n, void *cd);
264
265 /* Bidirectional Scattering Distribution Function */
266 struct BSDF_data {
267 int ninc; /* number of incoming directions */
268 int nout; /* number of outgoing directions */
269 float dim[3]; /* width, height, thickness (meters) */
270 char *mgf; /* geometric description (if any) */
271 void *ib_priv; /* input basis private data */
272 b_vecf2 *ib_vec; /* get input vector from index */
273 b_ndxf2 *ib_ndx; /* get input index from vector */
274 b_radf2 *ib_ohm; /* get input radius for index */
275 void *ob_priv; /* output basis private data */
276 b_vecf2 *ob_vec; /* get output vector from index */
277 b_ndxf2 *ob_ndx; /* get output index from vector */
278 b_radf2 *ob_ohm; /* get output radius for index */
279 float *bsdf; /* scattering distribution data */
280 }; /* bidirectional scattering distrib. func. */
281
282 #define getBSDF_incvec(v,b,i) (*(b)->ib_vec)(v,i,(b)->ib_priv)
283 #define getBSDF_incndx(b,v) (*(b)->ib_ndx)(v,(b)->ib_priv)
284 #define getBSDF_incohm(b,i) (*(b)->ib_ohm)(i,(b)->ib_priv)
285 #define getBSDF_outvec(v,b,o) (*(b)->ob_vec)(v,o,(b)->ob_priv)
286 #define getBSDF_outndx(b,v) (*(b)->ob_ndx)(v,(b)->ob_priv)
287 #define getBSDF_outohm(b,o) (*(b)->ob_ohm)(o,(b)->ob_priv)
288 #define BSDF_value(b,i,o) (b)->bsdf[(o)*(b)->ninc + (i)]
289
290 extern struct BSDF_data *load_BSDF(char *fname);
291 extern void free_BSDF(struct BSDF_data *b);
292 extern int r_BSDF_incvec(FVECT v, struct BSDF_data *b, int i,
293 double rv, MAT4 xm);
294 extern int r_BSDF_outvec(FVECT v, struct BSDF_data *b, int o,
295 double rv, MAT4 xm);
296 extern int getBSDF_xfm(MAT4 xm, FVECT nrm, UpDir ud, char *xfbuf);
297
298 /*######### END DEPRECATED DEFINITIONS #######*/
299 /*################################################################*/
300
301 #ifdef __cplusplus
302 }
303 #endif
304 #endif /* ! _BSDF_H_ */