-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathphotonmap_8cpp-source.html
545 lines (545 loc) · 97.4 KB
/
photonmap_8cpp-source.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>pbrt: photonmap.cpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.5.6 -->
<div class="navigation" id="top">
<div class="tabs">
<ul>
<li><a href="index.html"><span>Main Page</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li class="current"><a href="files.html"><span>Files</span></a></li>
</ul>
</div>
<h1>photonmap.cpp</h1><a href="photonmap_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001
<a name="l00002"></a>00002 <span class="comment">/*</span>
<a name="l00003"></a>00003 <span class="comment"> pbrt source code Copyright(c) 1998-2007 Matt Pharr and Greg Humphreys.</span>
<a name="l00004"></a>00004 <span class="comment"></span>
<a name="l00005"></a>00005 <span class="comment"> This file is part of pbrt.</span>
<a name="l00006"></a>00006 <span class="comment"></span>
<a name="l00007"></a>00007 <span class="comment"> pbrt is free software; you can redistribute it and/or modify</span>
<a name="l00008"></a>00008 <span class="comment"> it under the terms of the GNU General Public License as published by</span>
<a name="l00009"></a>00009 <span class="comment"> the Free Software Foundation; either version 2 of the License, or</span>
<a name="l00010"></a>00010 <span class="comment"> (at your option) any later version. Note that the text contents of</span>
<a name="l00011"></a>00011 <span class="comment"> the book "Physically Based Rendering" are *not* licensed under the</span>
<a name="l00012"></a>00012 <span class="comment"> GNU GPL.</span>
<a name="l00013"></a>00013 <span class="comment"></span>
<a name="l00014"></a>00014 <span class="comment"> pbrt is distributed in the hope that it will be useful,</span>
<a name="l00015"></a>00015 <span class="comment"> but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<a name="l00016"></a>00016 <span class="comment"> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<a name="l00017"></a>00017 <span class="comment"> GNU General Public License for more details.</span>
<a name="l00018"></a>00018 <span class="comment"></span>
<a name="l00019"></a>00019 <span class="comment"> You should have received a copy of the GNU General Public License</span>
<a name="l00020"></a>00020 <span class="comment"> along with this program. If not, see <http://www.gnu.org/licenses/>.</span>
<a name="l00021"></a>00021 <span class="comment"></span>
<a name="l00022"></a>00022 <span class="comment"> */</span>
<a name="l00023"></a>00023
<a name="l00024"></a>00024 <span class="comment">// photonmap.cpp*</span>
<a name="l00025"></a>00025 <span class="preprocessor">#include "<a class="code" href="pbrt_8h.html">pbrt.h</a>"</span>
<a name="l00026"></a>00026 <span class="preprocessor">#include "<a class="code" href="transport_8h.html">transport.h</a>"</span>
<a name="l00027"></a>00027 <span class="preprocessor">#include "<a class="code" href="scene_8h.html">scene.h</a>"</span>
<a name="l00028"></a>00028 <span class="preprocessor">#include "<a class="code" href="mc_8h.html">mc.h</a>"</span>
<a name="l00029"></a>00029 <span class="preprocessor">#include "<a class="code" href="kdtree_8h.html">kdtree.h</a>"</span>
<a name="l00030"></a>00030 <span class="preprocessor">#include "<a class="code" href="sampling_8h.html">sampling.h</a>"</span>
<a name="l00031"></a>00031 <span class="comment">// Photonmap Local Declarations</span>
<a name="l00032"></a>00032 <span class="keyword">struct </span><a class="code" href="structPhoton.html">Photon</a>;
<a name="l00033"></a>00033 <span class="keyword">struct </span><a class="code" href="structClosePhoton.html">ClosePhoton</a>;
<a name="l00034"></a>00034 <span class="keyword">struct </span><a class="code" href="structPhotonProcess.html">PhotonProcess</a>;
<a name="l00035"></a><a class="code" href="classPhotonIntegrator.html">00035</a> <span class="keyword">class </span><a class="code" href="classPhotonIntegrator.html">PhotonIntegrator</a> : <span class="keyword">public</span> <a class="code" href="classSurfaceIntegrator.html">SurfaceIntegrator</a> {
<a name="l00036"></a>00036 <span class="keyword">public</span>:
<a name="l00037"></a>00037 <span class="comment">// PhotonIntegrator Public Methods</span>
<a name="l00038"></a>00038 <a class="code" href="classPhotonIntegrator.html#b825c3516ca6f3f59a44f561d11e1e39">PhotonIntegrator</a>(<span class="keywordtype">int</span> ncaus, <span class="keywordtype">int</span> ndir, <span class="keywordtype">int</span> nindir, <span class="keywordtype">int</span> <a class="code" href="classPhotonIntegrator.html#109c50b0e93a3794714f0097067a8d3a">nLookup</a>, <span class="keywordtype">int</span> mdepth,
<a name="l00039"></a>00039 <span class="keywordtype">float</span> maxdist, <span class="keywordtype">bool</span> <a class="code" href="classPhotonIntegrator.html#82815c88dbee65f65bf7ad6cc2913366">finalGather</a>, <span class="keywordtype">int</span> <a class="code" href="classPhotonIntegrator.html#e7935d00219d736a590ff983d935d03c">gatherSamples</a>,
<a name="l00040"></a>00040 <span class="keywordtype">bool</span> <a class="code" href="classPhotonIntegrator.html#8a3aad58b4663515b13593d4bd992ad3">directWithPhotons</a>);
<a name="l00041"></a>00041 <a class="code" href="classPhotonIntegrator.html#816751b5480d321c96e6d3e06d46c9d0">~PhotonIntegrator</a>();
<a name="l00042"></a>00042 <a class="code" href="classSpectrum.html">Spectrum</a> <a class="code" href="classPhotonIntegrator.html#0187b1d5ee5c39649bc0edea115306d7">Li</a>(<span class="keyword">const</span> <a class="code" href="classScene.html">Scene</a> *scene, <span class="keyword">const</span> <a class="code" href="classRayDifferential.html">RayDifferential</a> &ray,
<a name="l00043"></a>00043 <span class="keyword">const</span> <a class="code" href="structSample.html">Sample</a> *sample, <span class="keywordtype">float</span> *alpha) <span class="keyword">const</span>;
<a name="l00044"></a>00044 <span class="keywordtype">void</span> <a class="code" href="classPhotonIntegrator.html#e68886adbc46d0311c45e6ed4c8eb7fc">RequestSamples</a>(<a class="code" href="structSample.html">Sample</a> *sample, <span class="keyword">const</span> <a class="code" href="classScene.html">Scene</a> *scene);
<a name="l00045"></a>00045 <span class="keywordtype">void</span> <a class="code" href="classPhotonIntegrator.html#51860b915e2808320434dce76de39092">Preprocess</a>(<span class="keyword">const</span> <a class="code" href="classScene.html">Scene</a> *);
<a name="l00046"></a>00046 <span class="keyword">private</span>:
<a name="l00047"></a>00047 <span class="comment">// PhotonIntegrator Private Methods</span>
<a name="l00048"></a><a class="code" href="classPhotonIntegrator.html#b7dd95304601f7e849db90682caa5594">00048</a> <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> <a class="code" href="classPhotonIntegrator.html#b7dd95304601f7e849db90682caa5594">unsuccessful</a>(<span class="keywordtype">int</span> needed, <span class="keywordtype">int</span> found, <span class="keywordtype">int</span> shot) {
<a name="l00049"></a>00049 <span class="keywordflow">return</span> (found < needed &&
<a name="l00050"></a>00050 (found == 0 || found < shot / 1024));
<a name="l00051"></a>00051 }
<a name="l00052"></a>00052 <span class="keyword">static</span> <a class="code" href="classSpectrum.html">Spectrum</a> <a class="code" href="classPhotonIntegrator.html#043826406cef3a743136fec3ae7d0c1f">LPhoton</a>(<a class="code" href="classKdTree.html">KdTree<Photon, PhotonProcess></a> *map,
<a name="l00053"></a>00053 <span class="keywordtype">int</span> nPaths, <span class="keywordtype">int</span> nLookup, <a class="code" href="classBSDF.html">BSDF</a> *bsdf, <span class="keyword">const</span> <a class="code" href="structIntersection.html">Intersection</a> &isect,
<a name="l00054"></a>00054 <span class="keyword">const</span> <a class="code" href="classVector.html">Vector</a> &w, <span class="keywordtype">float</span> <a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">maxDistSquared</a>);
<a name="l00055"></a>00055 <span class="comment">// PhotonIntegrator Private Data</span>
<a name="l00056"></a><a class="code" href="classPhotonIntegrator.html#55b4f5e91b4231ad536a8609fabc7442">00056</a> <a class="code" href="pbrt_8h.html#c319c165d52643e43249fe003e18bdf3">u_int</a> <a class="code" href="classPhotonIntegrator.html#0fa8dbe5f5ae311563cb5874be0477a5">nCausticPhotons</a>, <a class="code" href="classPhotonIntegrator.html#55b4f5e91b4231ad536a8609fabc7442">nIndirectPhotons</a>, <a class="code" href="classPhotonIntegrator.html#4c142d4a1e5b2bba18ea16fa6e2fe1a7">nDirectPhotons</a>;
<a name="l00057"></a><a class="code" href="classPhotonIntegrator.html#109c50b0e93a3794714f0097067a8d3a">00057</a> <a class="code" href="pbrt_8h.html#c319c165d52643e43249fe003e18bdf3">u_int</a> nLookup;
<a name="l00058"></a><a class="code" href="classPhotonIntegrator.html#269bcd41069dffb655a52f1e99effd81">00058</a> <span class="keyword">mutable</span> <span class="keywordtype">int</span> <a class="code" href="classPhotonIntegrator.html#269bcd41069dffb655a52f1e99effd81">specularDepth</a>;
<a name="l00059"></a><a class="code" href="classPhotonIntegrator.html#81b311d7c1cc3777af0c931c7378c5e1">00059</a> <span class="keywordtype">int</span> <a class="code" href="classPhotonIntegrator.html#81b311d7c1cc3777af0c931c7378c5e1">maxSpecularDepth</a>;
<a name="l00060"></a><a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">00060</a> <span class="keywordtype">float</span> <a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">maxDistSquared</a>;
<a name="l00061"></a><a class="code" href="classPhotonIntegrator.html#82815c88dbee65f65bf7ad6cc2913366">00061</a> <span class="keywordtype">bool</span> directWithPhotons, finalGather;
<a name="l00062"></a><a class="code" href="classPhotonIntegrator.html#e7935d00219d736a590ff983d935d03c">00062</a> <span class="keywordtype">int</span> gatherSamples;
<a name="l00063"></a>00063 <span class="comment">// Declare sample parameters for light source sampling</span>
<a name="l00064"></a><a class="code" href="classPhotonIntegrator.html#4013aa21a8ee2546aa99474f25eaa23f">00064</a> <span class="keywordtype">int</span> *<a class="code" href="classPhotonIntegrator.html#4013aa21a8ee2546aa99474f25eaa23f">lightSampleOffset</a>, <a class="code" href="classPhotonIntegrator.html#bc7d611d219ed24b16a8e293948bc1b6">lightNumOffset</a>;
<a name="l00065"></a><a class="code" href="classPhotonIntegrator.html#8709a8a6facd8ff4b5f4893b20cd57a2">00065</a> <span class="keywordtype">int</span> *<a class="code" href="classPhotonIntegrator.html#8709a8a6facd8ff4b5f4893b20cd57a2">bsdfSampleOffset</a>, *<a class="code" href="classPhotonIntegrator.html#c41ce1a769442e7112e77a189df97cd2">bsdfComponentOffset</a>;
<a name="l00066"></a><a class="code" href="classPhotonIntegrator.html#eab686612dd48fec04cbcc28918ff560">00066</a> <span class="keywordtype">int</span> <a class="code" href="classPhotonIntegrator.html#eab686612dd48fec04cbcc28918ff560">gatherSampleOffset</a>, <a class="code" href="classPhotonIntegrator.html#dbf0bf147f2caf1bdeeeced3498e0404">gatherComponentOffset</a>;
<a name="l00067"></a><a class="code" href="classPhotonIntegrator.html#904efc498424ac1a613bf44451386ddb">00067</a> <span class="keywordtype">int</span> <a class="code" href="classPhotonIntegrator.html#8dea7dd8abb3a05f9b0f63e83dce192c">nCausticPaths</a>, <a class="code" href="classPhotonIntegrator.html#b381d714f5e64926a4d9e75d95f35a28">nDirectPaths</a>, <a class="code" href="classPhotonIntegrator.html#904efc498424ac1a613bf44451386ddb">nIndirectPaths</a>;
<a name="l00068"></a><a class="code" href="classPhotonIntegrator.html#85c50f55232492130ce83f2bbdcb7efe">00068</a> <span class="keyword">mutable</span> <a class="code" href="classKdTree.html">KdTree<Photon, PhotonProcess></a> *<a class="code" href="classPhotonIntegrator.html#85c50f55232492130ce83f2bbdcb7efe">causticMap</a>;
<a name="l00069"></a><a class="code" href="classPhotonIntegrator.html#8d035fec0e4d3b37e2f1d2dd13c6d46f">00069</a> <span class="keyword">mutable</span> <a class="code" href="classKdTree.html">KdTree<Photon, PhotonProcess></a> *<a class="code" href="classPhotonIntegrator.html#8d035fec0e4d3b37e2f1d2dd13c6d46f">directMap</a>;
<a name="l00070"></a><a class="code" href="classPhotonIntegrator.html#56063efc17dae052295962d1f8a33f02">00070</a> <span class="keyword">mutable</span> <a class="code" href="classKdTree.html">KdTree<Photon, PhotonProcess></a> *<a class="code" href="classPhotonIntegrator.html#56063efc17dae052295962d1f8a33f02">indirectMap</a>;
<a name="l00071"></a>00071 };
<a name="l00072"></a>00072 <span class="keyword">struct </span><a class="code" href="structPhoton.html">Photon</a> {
<a name="l00073"></a>00073 <span class="comment">// Photon Constructor</span>
<a name="l00074"></a><a class="code" href="structPhoton.html#f35c1c18bc3acd5c5cb8792cea7f418b">00074</a> <a class="code" href="structPhoton.html#962be18928ae3923586487eae3bd5ce0">Photon</a>(<span class="keyword">const</span> <a class="code" href="classPoint.html">Point</a> &pp, <span class="keyword">const</span> <a class="code" href="classSpectrum.html">Spectrum</a> &wt, <span class="keyword">const</span> <a class="code" href="classVector.html">Vector</a> &w)
<a name="l00075"></a>00075 : <a class="code" href="structPhoton.html#d742a652b6d2257266bcb07318e0fd32">p</a>(pp), <a class="code" href="structPhoton.html#621db8918d36d1da824751226522e0bd">alpha</a>(wt), <a class="code" href="structPhoton.html#42df773350d698bc500e7dad63c148be">wi</a>(w) {
<a name="l00076"></a>00076 }
<a name="l00077"></a><a class="code" href="structPhoton.html#962be18928ae3923586487eae3bd5ce0">00077</a> <a class="code" href="structPhoton.html#962be18928ae3923586487eae3bd5ce0">Photon</a>() { }
<a name="l00078"></a>00078 <a class="code" href="classPoint.html">Point</a> <a class="code" href="structPhoton.html#d742a652b6d2257266bcb07318e0fd32">p</a>;
<a name="l00079"></a>00079 <a class="code" href="classSpectrum.html">Spectrum</a> <a class="code" href="structPhoton.html#621db8918d36d1da824751226522e0bd">alpha</a>;
<a name="l00080"></a>00080 <a class="code" href="classVector.html">Vector</a> <a class="code" href="structPhoton.html#42df773350d698bc500e7dad63c148be">wi</a>;
<a name="l00081"></a>00081 };
<a name="l00082"></a>00082 <span class="keyword">struct </span><a class="code" href="structPhotonProcess.html">PhotonProcess</a> {
<a name="l00083"></a>00083 <span class="comment">// PhotonProcess Public Methods</span>
<a name="l00084"></a>00084 <a class="code" href="structPhotonProcess.html#a13db99c30b2fd91445827345393b295">PhotonProcess</a>(<a class="code" href="pbrt_8h.html#c319c165d52643e43249fe003e18bdf3">u_int</a> mp, <span class="keyword">const</span> <a class="code" href="classPoint.html">Point</a> &<a class="code" href="structPhotonProcess.html#dafcd38c8fcdf0a3a68ee0f3661173ce">p</a>);
<a name="l00085"></a>00085 <span class="keywordtype">void</span> <a class="code" href="structPhotonProcess.html#063ad32af5b764ffc566778d03c26c59">operator()</a>(<span class="keyword">const</span> <a class="code" href="structPhoton.html">Photon</a> &photon, <span class="keywordtype">float</span> dist2, <span class="keywordtype">float</span> &maxDistSquared) <span class="keyword">const</span>;
<a name="l00086"></a>00086 <span class="keyword">const</span> <a class="code" href="classPoint.html">Point</a> &<a class="code" href="structPhotonProcess.html#dafcd38c8fcdf0a3a68ee0f3661173ce">p</a>;
<a name="l00087"></a>00087 <a class="code" href="structClosePhoton.html">ClosePhoton</a> *<a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>;
<a name="l00088"></a>00088 <a class="code" href="pbrt_8h.html#c319c165d52643e43249fe003e18bdf3">u_int</a> <a class="code" href="structPhotonProcess.html#5abce4cbd14d9f3e230a5f4d24b590ed">nLookup</a>;
<a name="l00089"></a>00089 <span class="keyword">mutable</span> <a class="code" href="pbrt_8h.html#c319c165d52643e43249fe003e18bdf3">u_int</a> <a class="code" href="structPhotonProcess.html#8d8f89eaffea3032799d1cd4587ac9e2">foundPhotons</a>;
<a name="l00090"></a>00090 };
<a name="l00091"></a>00091 <span class="keyword">struct </span><a class="code" href="structClosePhoton.html">ClosePhoton</a> {
<a name="l00092"></a><a class="code" href="structClosePhoton.html#e59579ed4f807caf428455b2e181ebda">00092</a> <a class="code" href="structClosePhoton.html#e59579ed4f807caf428455b2e181ebda">ClosePhoton</a>(<span class="keyword">const</span> <a class="code" href="structPhoton.html">Photon</a> *p = NULL,
<a name="l00093"></a>00093 <span class="keywordtype">float</span> md2 = <a class="code" href="pbrt_8h.html#956e2723d559858d08644ac99146e910">INFINITY</a>) {
<a name="l00094"></a>00094 <a class="code" href="structClosePhoton.html#5fa7f65d8cefe4b33324c636cc7e682d">photon</a> = p;
<a name="l00095"></a>00095 <a class="code" href="structClosePhoton.html#0a204e03ad7c91dbd2e1dcf949282c7e">distanceSquared</a> = md2;
<a name="l00096"></a>00096 }
<a name="l00097"></a><a class="code" href="structClosePhoton.html#8919a9e5840dc65b2db2a4d5d19fd150">00097</a> <span class="keywordtype">bool</span> <a class="code" href="structClosePhoton.html#8919a9e5840dc65b2db2a4d5d19fd150">operator<</a>(<span class="keyword">const</span> <a class="code" href="structClosePhoton.html">ClosePhoton</a> &p2)<span class="keyword"> const </span>{
<a name="l00098"></a>00098 <span class="keywordflow">return</span> <a class="code" href="structClosePhoton.html#0a204e03ad7c91dbd2e1dcf949282c7e">distanceSquared</a> == p2.<a class="code" href="structClosePhoton.html#0a204e03ad7c91dbd2e1dcf949282c7e">distanceSquared</a> ? (<a class="code" href="structClosePhoton.html#5fa7f65d8cefe4b33324c636cc7e682d">photon</a> < p2.<a class="code" href="structClosePhoton.html#5fa7f65d8cefe4b33324c636cc7e682d">photon</a>) :
<a name="l00099"></a>00099 <a class="code" href="structClosePhoton.html#0a204e03ad7c91dbd2e1dcf949282c7e">distanceSquared</a> < p2.<a class="code" href="structClosePhoton.html#0a204e03ad7c91dbd2e1dcf949282c7e">distanceSquared</a>;
<a name="l00100"></a>00100 }
<a name="l00101"></a>00101 <span class="keyword">const</span> <a class="code" href="structPhoton.html">Photon</a> *<a class="code" href="structClosePhoton.html#5fa7f65d8cefe4b33324c636cc7e682d">photon</a>;
<a name="l00102"></a>00102 <span class="keywordtype">float</span> <a class="code" href="structClosePhoton.html#0a204e03ad7c91dbd2e1dcf949282c7e">distanceSquared</a>;
<a name="l00103"></a>00103 };
<a name="l00104"></a>00104 <span class="comment">// Photonmap Method Definitions</span>
<a name="l00105"></a><a class="code" href="classPhotonIntegrator.html#b825c3516ca6f3f59a44f561d11e1e39">00105</a> <a class="code" href="classPhotonIntegrator.html#b825c3516ca6f3f59a44f561d11e1e39">PhotonIntegrator::PhotonIntegrator</a>(<span class="keywordtype">int</span> ncaus, <span class="keywordtype">int</span> ndir, <span class="keywordtype">int</span> nind,
<a name="l00106"></a>00106 <span class="keywordtype">int</span> nl, <span class="keywordtype">int</span> mdepth, <span class="keywordtype">float</span> mdist, <span class="keywordtype">bool</span> fg,
<a name="l00107"></a>00107 <span class="keywordtype">int</span> gs, <span class="keywordtype">bool</span> dp) {
<a name="l00108"></a>00108 <a class="code" href="classPhotonIntegrator.html#0fa8dbe5f5ae311563cb5874be0477a5">nCausticPhotons</a> = ncaus;
<a name="l00109"></a>00109 <a class="code" href="classPhotonIntegrator.html#55b4f5e91b4231ad536a8609fabc7442">nIndirectPhotons</a> = nind;
<a name="l00110"></a>00110 <a class="code" href="classPhotonIntegrator.html#4c142d4a1e5b2bba18ea16fa6e2fe1a7">nDirectPhotons</a> = ndir;
<a name="l00111"></a>00111 <a class="code" href="classPhotonIntegrator.html#109c50b0e93a3794714f0097067a8d3a">nLookup</a> = nl;
<a name="l00112"></a>00112 <a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">maxDistSquared</a> = mdist * mdist;
<a name="l00113"></a>00113 <a class="code" href="classPhotonIntegrator.html#81b311d7c1cc3777af0c931c7378c5e1">maxSpecularDepth</a> = mdepth;
<a name="l00114"></a>00114 <a class="code" href="classPhotonIntegrator.html#85c50f55232492130ce83f2bbdcb7efe">causticMap</a> = <a class="code" href="classPhotonIntegrator.html#8d035fec0e4d3b37e2f1d2dd13c6d46f">directMap</a> = <a class="code" href="classPhotonIntegrator.html#56063efc17dae052295962d1f8a33f02">indirectMap</a> = NULL;
<a name="l00115"></a>00115 <a class="code" href="classPhotonIntegrator.html#269bcd41069dffb655a52f1e99effd81">specularDepth</a> = 0;
<a name="l00116"></a>00116 <a class="code" href="classPhotonIntegrator.html#82815c88dbee65f65bf7ad6cc2913366">finalGather</a> = fg;
<a name="l00117"></a>00117 <a class="code" href="classPhotonIntegrator.html#e7935d00219d736a590ff983d935d03c">gatherSamples</a> = gs;
<a name="l00118"></a>00118 <a class="code" href="classPhotonIntegrator.html#8a3aad58b4663515b13593d4bd992ad3">directWithPhotons</a> = dp;
<a name="l00119"></a>00119 }
<a name="l00120"></a><a class="code" href="classPhotonIntegrator.html#816751b5480d321c96e6d3e06d46c9d0">00120</a> <a class="code" href="classPhotonIntegrator.html#816751b5480d321c96e6d3e06d46c9d0">PhotonIntegrator::~PhotonIntegrator</a>() {
<a name="l00121"></a>00121 <span class="keyword">delete</span> <a class="code" href="classPhotonIntegrator.html#85c50f55232492130ce83f2bbdcb7efe">causticMap</a>;
<a name="l00122"></a>00122 <span class="keyword">delete</span> <a class="code" href="classPhotonIntegrator.html#8d035fec0e4d3b37e2f1d2dd13c6d46f">directMap</a>;
<a name="l00123"></a>00123 <span class="keyword">delete</span> <a class="code" href="classPhotonIntegrator.html#56063efc17dae052295962d1f8a33f02">indirectMap</a>;
<a name="l00124"></a>00124 }
<a name="l00125"></a><a class="code" href="classPhotonIntegrator.html#e68886adbc46d0311c45e6ed4c8eb7fc">00125</a> <span class="keywordtype">void</span> <a class="code" href="classPhotonIntegrator.html#e68886adbc46d0311c45e6ed4c8eb7fc">PhotonIntegrator::RequestSamples</a>(<a class="code" href="structSample.html">Sample</a> *sample,
<a name="l00126"></a>00126 <span class="keyword">const</span> <a class="code" href="classScene.html">Scene</a> *scene) {
<a name="l00127"></a>00127 <span class="comment">// Allocate and request samples for sampling all lights</span>
<a name="l00128"></a>00128 <a class="code" href="pbrt_8h.html#c319c165d52643e43249fe003e18bdf3">u_int</a> nLights = scene-><a class="code" href="classScene.html#546553c8f864fd2aa709ad95a1d5ecc9">lights</a>.size();
<a name="l00129"></a>00129 <a class="code" href="classPhotonIntegrator.html#4013aa21a8ee2546aa99474f25eaa23f">lightSampleOffset</a> = <span class="keyword">new</span> <span class="keywordtype">int</span>[nLights];
<a name="l00130"></a>00130 <a class="code" href="classPhotonIntegrator.html#8709a8a6facd8ff4b5f4893b20cd57a2">bsdfSampleOffset</a> = <span class="keyword">new</span> <span class="keywordtype">int</span>[nLights];
<a name="l00131"></a>00131 <a class="code" href="classPhotonIntegrator.html#c41ce1a769442e7112e77a189df97cd2">bsdfComponentOffset</a> = <span class="keyword">new</span> <span class="keywordtype">int</span>[nLights];
<a name="l00132"></a>00132 <span class="keywordflow">for</span> (<a class="code" href="pbrt_8h.html#c319c165d52643e43249fe003e18bdf3">u_int</a> i = 0; i < nLights; ++i) {
<a name="l00133"></a>00133 <span class="keyword">const</span> <a class="code" href="classLight.html">Light</a> *light = scene-><a class="code" href="classScene.html#546553c8f864fd2aa709ad95a1d5ecc9">lights</a>[i];
<a name="l00134"></a>00134 <span class="keywordtype">int</span> lightSamples =
<a name="l00135"></a>00135 scene-><a class="code" href="classScene.html#69e1a55e5efa7f323049dd06688abb49">sampler</a>-><a class="code" href="classSampler.html#d2ca20cd81ffb6fc242c3f0cf6c9812f">RoundSize</a>(light-><a class="code" href="classLight.html#fae2e64a4a14046913c82c175078d8bb">nSamples</a>);
<a name="l00136"></a>00136 <a class="code" href="classPhotonIntegrator.html#4013aa21a8ee2546aa99474f25eaa23f">lightSampleOffset</a>[i] = sample-><a class="code" href="structSample.html#21b7f539ec14f3b5c7bdddf790e1b8a7">Add2D</a>(lightSamples);
<a name="l00137"></a>00137 <a class="code" href="classPhotonIntegrator.html#8709a8a6facd8ff4b5f4893b20cd57a2">bsdfSampleOffset</a>[i] = sample-><a class="code" href="structSample.html#21b7f539ec14f3b5c7bdddf790e1b8a7">Add2D</a>(lightSamples);
<a name="l00138"></a>00138 <a class="code" href="classPhotonIntegrator.html#c41ce1a769442e7112e77a189df97cd2">bsdfComponentOffset</a>[i] = sample-><a class="code" href="structSample.html#a2b567c5a4160488ba81953b59df59f0">Add1D</a>(lightSamples);
<a name="l00139"></a>00139 }
<a name="l00140"></a>00140 <a class="code" href="classPhotonIntegrator.html#bc7d611d219ed24b16a8e293948bc1b6">lightNumOffset</a> = -1;
<a name="l00141"></a>00141 <span class="keywordflow">if</span> (<a class="code" href="classPhotonIntegrator.html#82815c88dbee65f65bf7ad6cc2913366">finalGather</a>) {
<a name="l00142"></a>00142 <a class="code" href="classPhotonIntegrator.html#e7935d00219d736a590ff983d935d03c">gatherSamples</a> = scene-><a class="code" href="classScene.html#69e1a55e5efa7f323049dd06688abb49">sampler</a>-><a class="code" href="classSampler.html#d2ca20cd81ffb6fc242c3f0cf6c9812f">RoundSize</a>(<a class="code" href="classPhotonIntegrator.html#e7935d00219d736a590ff983d935d03c">gatherSamples</a>);
<a name="l00143"></a>00143 <a class="code" href="classPhotonIntegrator.html#eab686612dd48fec04cbcc28918ff560">gatherSampleOffset</a> = sample-><a class="code" href="structSample.html#21b7f539ec14f3b5c7bdddf790e1b8a7">Add2D</a>(<a class="code" href="classPhotonIntegrator.html#e7935d00219d736a590ff983d935d03c">gatherSamples</a>);
<a name="l00144"></a>00144 <a class="code" href="classPhotonIntegrator.html#dbf0bf147f2caf1bdeeeced3498e0404">gatherComponentOffset</a> = sample-><a class="code" href="structSample.html#a2b567c5a4160488ba81953b59df59f0">Add1D</a>(<a class="code" href="classPhotonIntegrator.html#e7935d00219d736a590ff983d935d03c">gatherSamples</a>);
<a name="l00145"></a>00145 }
<a name="l00146"></a>00146 }
<a name="l00147"></a><a class="code" href="classPhotonIntegrator.html#51860b915e2808320434dce76de39092">00147</a> <span class="keywordtype">void</span> <a class="code" href="classPhotonIntegrator.html#51860b915e2808320434dce76de39092">PhotonIntegrator::Preprocess</a>(<span class="keyword">const</span> <a class="code" href="classScene.html">Scene</a> *scene) {
<a name="l00148"></a>00148 <span class="keywordflow">if</span> (scene-><a class="code" href="classScene.html#546553c8f864fd2aa709ad95a1d5ecc9">lights</a>.size() == 0) <span class="keywordflow">return</span>;
<a name="l00149"></a>00149 <a class="code" href="structProgressReporter.html">ProgressReporter</a> progress(<a class="code" href="classPhotonIntegrator.html#0fa8dbe5f5ae311563cb5874be0477a5">nCausticPhotons</a>+<a class="code" href="classPhotonIntegrator.html#4c142d4a1e5b2bba18ea16fa6e2fe1a7">nDirectPhotons</a>+ <span class="comment">// NOBOOK</span>
<a name="l00150"></a>00150 <a class="code" href="classPhotonIntegrator.html#55b4f5e91b4231ad536a8609fabc7442">nIndirectPhotons</a>, <span class="stringliteral">"Shooting photons"</span>); <span class="comment">// NOBOOK</span>
<a name="l00151"></a>00151 vector<Photon> causticPhotons;
<a name="l00152"></a>00152 vector<Photon> directPhotons;
<a name="l00153"></a>00153 vector<Photon> indirectPhotons;
<a name="l00154"></a>00154 causticPhotons.reserve(<a class="code" href="classPhotonIntegrator.html#0fa8dbe5f5ae311563cb5874be0477a5">nCausticPhotons</a>); <span class="comment">// NOBOOK</span>
<a name="l00155"></a>00155 directPhotons.reserve(<a class="code" href="classPhotonIntegrator.html#4c142d4a1e5b2bba18ea16fa6e2fe1a7">nDirectPhotons</a>); <span class="comment">// NOBOOK</span>
<a name="l00156"></a>00156 indirectPhotons.reserve(<a class="code" href="classPhotonIntegrator.html#55b4f5e91b4231ad536a8609fabc7442">nIndirectPhotons</a>); <span class="comment">// NOBOOK</span>
<a name="l00157"></a>00157 <span class="comment">// Initialize photon shooting statistics</span>
<a name="l00158"></a>00158 <span class="keyword">static</span> <a class="code" href="classStatsCounter.html">StatsCounter</a> nshot(<span class="stringliteral">"Photon Map"</span>,
<a name="l00159"></a>00159 <span class="stringliteral">"Number of photons shot from lights"</span>);
<a name="l00160"></a>00160 <span class="keywordtype">bool</span> causticDone = (<a class="code" href="classPhotonIntegrator.html#0fa8dbe5f5ae311563cb5874be0477a5">nCausticPhotons</a> == 0);
<a name="l00161"></a>00161 <span class="keywordtype">bool</span> directDone = (<a class="code" href="classPhotonIntegrator.html#4c142d4a1e5b2bba18ea16fa6e2fe1a7">nDirectPhotons</a> == 0);
<a name="l00162"></a>00162 <span class="keywordtype">bool</span> indirectDone = (<a class="code" href="classPhotonIntegrator.html#55b4f5e91b4231ad536a8609fabc7442">nIndirectPhotons</a> == 0);
<a name="l00163"></a>00163 <span class="keywordflow">while</span> (!causticDone || !directDone || !indirectDone) {
<a name="l00164"></a>00164 ++nshot;
<a name="l00165"></a>00165 <span class="comment">// Give up if we're not storing enough photons</span>
<a name="l00166"></a>00166 <span class="keywordflow">if</span> (nshot > 500000 &&
<a name="l00167"></a>00167 (<a class="code" href="classPhotonIntegrator.html#b7dd95304601f7e849db90682caa5594">unsuccessful</a>(<a class="code" href="classPhotonIntegrator.html#0fa8dbe5f5ae311563cb5874be0477a5">nCausticPhotons</a>,
<a name="l00168"></a>00168 causticPhotons.size(),
<a name="l00169"></a>00169 nshot) ||
<a name="l00170"></a>00170 <a class="code" href="classPhotonIntegrator.html#b7dd95304601f7e849db90682caa5594">unsuccessful</a>(<a class="code" href="classPhotonIntegrator.html#4c142d4a1e5b2bba18ea16fa6e2fe1a7">nDirectPhotons</a>,
<a name="l00171"></a>00171 directPhotons.size(),
<a name="l00172"></a>00172 nshot) ||
<a name="l00173"></a>00173 <a class="code" href="classPhotonIntegrator.html#b7dd95304601f7e849db90682caa5594">unsuccessful</a>(<a class="code" href="classPhotonIntegrator.html#55b4f5e91b4231ad536a8609fabc7442">nIndirectPhotons</a>,
<a name="l00174"></a>00174 indirectPhotons.size(),
<a name="l00175"></a>00175 nshot))) {
<a name="l00176"></a>00176 <a class="code" href="pbrt_8h.html#d1a16fc9ced4ddc376b9d3e6607be15e">Error</a>(<span class="stringliteral">"Unable to store enough photons. Giving up.\n"</span>);
<a name="l00177"></a>00177 <span class="keywordflow">return</span>;
<a name="l00178"></a>00178 }
<a name="l00179"></a>00179 <span class="comment">// Trace a photon path and store contribution</span>
<a name="l00180"></a>00180 <span class="comment">// Choose 4D sample values for photon</span>
<a name="l00181"></a>00181 <span class="keywordtype">float</span> u[4];
<a name="l00182"></a>00182 u[0] = (float)<a class="code" href="sampling_8h.html#4d347f21afe7a5bf94d9e8149dfdea00">RadicalInverse</a>((<span class="keywordtype">int</span>)nshot+1, 2);
<a name="l00183"></a>00183 u[1] = (float)<a class="code" href="sampling_8h.html#4d347f21afe7a5bf94d9e8149dfdea00">RadicalInverse</a>((<span class="keywordtype">int</span>)nshot+1, 3);
<a name="l00184"></a>00184 u[2] = (float)<a class="code" href="sampling_8h.html#4d347f21afe7a5bf94d9e8149dfdea00">RadicalInverse</a>((<span class="keywordtype">int</span>)nshot+1, 5);
<a name="l00185"></a>00185 u[3] = (float)<a class="code" href="sampling_8h.html#4d347f21afe7a5bf94d9e8149dfdea00">RadicalInverse</a>((<span class="keywordtype">int</span>)nshot+1, 7);
<a name="l00186"></a>00186 <span class="comment">// Choose light to shoot photon from</span>
<a name="l00187"></a>00187 <span class="keywordtype">int</span> nLights = int(scene-><a class="code" href="classScene.html#546553c8f864fd2aa709ad95a1d5ecc9">lights</a>.size());
<a name="l00188"></a>00188 <span class="keywordtype">int</span> lightNum =
<a name="l00189"></a>00189 min(<a class="code" href="pbrt_8h.html#02648670ea7bf29f5782902cd9aa87c1">Floor2Int</a>(nLights * (<span class="keywordtype">float</span>)<a class="code" href="sampling_8h.html#4d347f21afe7a5bf94d9e8149dfdea00">RadicalInverse</a>((<span class="keywordtype">int</span>)nshot+1, 11)),
<a name="l00190"></a>00190 nLights-1);
<a name="l00191"></a>00191 <a class="code" href="classLight.html">Light</a> *light = scene-><a class="code" href="classScene.html#546553c8f864fd2aa709ad95a1d5ecc9">lights</a>[lightNum];
<a name="l00192"></a>00192 <span class="keywordtype">float</span> lightPdf = 1.f / nLights;
<a name="l00193"></a>00193 <span class="comment">// Generate _photonRay_ from light source and initialize _alpha_</span>
<a name="l00194"></a>00194 <a class="code" href="classRayDifferential.html">RayDifferential</a> photonRay;
<a name="l00195"></a>00195 <span class="keywordtype">float</span> pdf;
<a name="l00196"></a>00196 <a class="code" href="classSpectrum.html">Spectrum</a> alpha =
<a name="l00197"></a>00197 light-><a class="code" href="classLight.html#cc1f14dae6074cc9c16b7387020e814c">Sample_L</a>(scene, u[0], u[1], u[2], u[3],
<a name="l00198"></a>00198 &photonRay, &pdf);
<a name="l00199"></a>00199 <span class="keywordflow">if</span> (pdf == 0.f || alpha.<a class="code" href="classSpectrum.html#a05b9a07476998192a83fcd015b7619f">Black</a>()) <span class="keywordflow">continue</span>;
<a name="l00200"></a>00200 alpha /= pdf * lightPdf;
<a name="l00201"></a>00201 <span class="keywordflow">if</span> (!alpha.<a class="code" href="classSpectrum.html#a05b9a07476998192a83fcd015b7619f">Black</a>()) {
<a name="l00202"></a>00202 <span class="comment">// Follow photon path through scene and record intersections</span>
<a name="l00203"></a>00203 <span class="keywordtype">bool</span> specularPath = <span class="keyword">false</span>;
<a name="l00204"></a>00204 <a class="code" href="structIntersection.html">Intersection</a> photonIsect;
<a name="l00205"></a>00205 <span class="keywordtype">int</span> nIntersections = 0;
<a name="l00206"></a>00206 <span class="keywordflow">while</span> (scene-><a class="code" href="classScene.html#36f27fc416cc5b53fe03575e2d15803a">Intersect</a>(photonRay, &photonIsect)) {
<a name="l00207"></a>00207 ++nIntersections;
<a name="l00208"></a>00208 <span class="comment">// Handle photon/surface intersection</span>
<a name="l00209"></a>00209 alpha *= scene-><a class="code" href="classScene.html#c80ef18b12e54a64a809de677aada2e9">Transmittance</a>(photonRay);
<a name="l00210"></a>00210 <a class="code" href="classVector.html">Vector</a> wo = -photonRay.<a class="code" href="classRay.html#5bbfc94e178e0a050b51200acc579069">d</a>;
<a name="l00211"></a>00211 <a class="code" href="classBSDF.html">BSDF</a> *photonBSDF = photonIsect.<a class="code" href="structIntersection.html#ff18bb39143b49fa340a3697b9c606b5">GetBSDF</a>(photonRay);
<a name="l00212"></a>00212 <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730">BxDFType</a> specularType = <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730">BxDFType</a>(<a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e6697304331da0ab7ddceadcfffa81ecf70577e">BSDF_REFLECTION</a> |
<a name="l00213"></a>00213 <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730806674394a395d5dc6383956e4f2733f">BSDF_TRANSMISSION</a> | <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730c94ee1d195ff19883a79d1c08bd773d9">BSDF_SPECULAR</a>);
<a name="l00214"></a>00214 <span class="keywordtype">bool</span> hasNonSpecular = (photonBSDF-><a class="code" href="classBSDF.html#e6d4c9a1826621a887a4ccd7fa7b5222">NumComponents</a>() >
<a name="l00215"></a>00215 photonBSDF-><a class="code" href="classBSDF.html#e6d4c9a1826621a887a4ccd7fa7b5222">NumComponents</a>(specularType));
<a name="l00216"></a>00216 <span class="keywordflow">if</span> (hasNonSpecular) {
<a name="l00217"></a>00217 <span class="comment">// Deposit photon at surface</span>
<a name="l00218"></a>00218 <a class="code" href="structPhoton.html">Photon</a> photon(photonIsect.<a class="code" href="structIntersection.html#27a04b9f68291416c4d864f105a7d991">dg</a>.<a class="code" href="structDifferentialGeometry.html#3d5353db1c1a6a93ef6da642d064f46e">p</a>, alpha, wo);
<a name="l00219"></a>00219 <span class="keywordflow">if</span> (nIntersections == 1) {
<a name="l00220"></a>00220 <span class="comment">// Process direct lighting photon intersection</span>
<a name="l00221"></a>00221 <span class="keywordflow">if</span> (!directDone) {
<a name="l00222"></a>00222 directPhotons.push_back(photon);
<a name="l00223"></a>00223 <span class="keywordflow">if</span> (directPhotons.size() == <a class="code" href="classPhotonIntegrator.html#4c142d4a1e5b2bba18ea16fa6e2fe1a7">nDirectPhotons</a>) {
<a name="l00224"></a>00224 directDone = <span class="keyword">true</span>;
<a name="l00225"></a>00225 <a class="code" href="classPhotonIntegrator.html#b381d714f5e64926a4d9e75d95f35a28">nDirectPaths</a> = (int)nshot;
<a name="l00226"></a>00226 <a class="code" href="classPhotonIntegrator.html#8d035fec0e4d3b37e2f1d2dd13c6d46f">directMap</a> =
<a name="l00227"></a>00227 <span class="keyword">new</span> <a class="code" href="classKdTree.html">KdTree</a><<a class="code" href="structPhoton.html">Photon</a>,
<a name="l00228"></a>00228 <a class="code" href="structPhotonProcess.html">PhotonProcess</a>>(directPhotons);
<a name="l00229"></a>00229 }
<a name="l00230"></a>00230 progress.<a class="code" href="structProgressReporter.html#deb36328289f937ca81e457f78781faa">Update</a>(); <span class="comment">// NOBOOK</span>
<a name="l00231"></a>00231 }
<a name="l00232"></a>00232 }
<a name="l00233"></a>00233 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (specularPath) {
<a name="l00234"></a>00234 <span class="comment">// Process caustic photon intersection</span>
<a name="l00235"></a>00235 <span class="keywordflow">if</span> (!causticDone) {
<a name="l00236"></a>00236 causticPhotons.push_back(photon);
<a name="l00237"></a>00237 <span class="keywordflow">if</span> (causticPhotons.size() == <a class="code" href="classPhotonIntegrator.html#0fa8dbe5f5ae311563cb5874be0477a5">nCausticPhotons</a>) {
<a name="l00238"></a>00238 causticDone = <span class="keyword">true</span>;
<a name="l00239"></a>00239 <a class="code" href="classPhotonIntegrator.html#8dea7dd8abb3a05f9b0f63e83dce192c">nCausticPaths</a> = (int)nshot;
<a name="l00240"></a>00240 <a class="code" href="classPhotonIntegrator.html#85c50f55232492130ce83f2bbdcb7efe">causticMap</a> =
<a name="l00241"></a>00241 <span class="keyword">new</span> <a class="code" href="classKdTree.html">KdTree</a><<a class="code" href="structPhoton.html">Photon</a>,
<a name="l00242"></a>00242 <a class="code" href="structPhotonProcess.html">PhotonProcess</a>>(causticPhotons);
<a name="l00243"></a>00243 }
<a name="l00244"></a>00244 progress.<a class="code" href="structProgressReporter.html#deb36328289f937ca81e457f78781faa">Update</a>();
<a name="l00245"></a>00245 }
<a name="l00246"></a>00246 }
<a name="l00247"></a>00247 <span class="keywordflow">else</span> {
<a name="l00248"></a>00248 <span class="comment">// Process indirect lighting photon intersection</span>
<a name="l00249"></a>00249 <span class="keywordflow">if</span> (!indirectDone) {
<a name="l00250"></a>00250 indirectPhotons.push_back(photon);
<a name="l00251"></a>00251 <span class="keywordflow">if</span> (indirectPhotons.size() == <a class="code" href="classPhotonIntegrator.html#55b4f5e91b4231ad536a8609fabc7442">nIndirectPhotons</a>) {
<a name="l00252"></a>00252 indirectDone = <span class="keyword">true</span>;
<a name="l00253"></a>00253 <a class="code" href="classPhotonIntegrator.html#904efc498424ac1a613bf44451386ddb">nIndirectPaths</a> = (int)nshot;
<a name="l00254"></a>00254 <a class="code" href="classPhotonIntegrator.html#56063efc17dae052295962d1f8a33f02">indirectMap</a> =
<a name="l00255"></a>00255 <span class="keyword">new</span> <a class="code" href="classKdTree.html">KdTree</a><<a class="code" href="structPhoton.html">Photon</a>,
<a name="l00256"></a>00256 <a class="code" href="structPhotonProcess.html">PhotonProcess</a>>(indirectPhotons);
<a name="l00257"></a>00257 }
<a name="l00258"></a>00258 progress.<a class="code" href="structProgressReporter.html#deb36328289f937ca81e457f78781faa">Update</a>();
<a name="l00259"></a>00259 }
<a name="l00260"></a>00260 }
<a name="l00261"></a>00261 }
<a name="l00262"></a>00262 <span class="comment">// Sample new photon ray direction</span>
<a name="l00263"></a>00263 <a class="code" href="classVector.html">Vector</a> wi;
<a name="l00264"></a>00264 <span class="keywordtype">float</span> pdf;
<a name="l00265"></a>00265 <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730">BxDFType</a> flags;
<a name="l00266"></a>00266 <span class="comment">// Get random numbers for sampling outgoing photon direction</span>
<a name="l00267"></a>00267 <span class="keywordtype">float</span> u1, u2, u3;
<a name="l00268"></a>00268 <span class="keywordflow">if</span> (nIntersections == 1) {
<a name="l00269"></a>00269 u1 = (float)<a class="code" href="sampling_8h.html#4d347f21afe7a5bf94d9e8149dfdea00">RadicalInverse</a>((<span class="keywordtype">int</span>)nshot+1, 13);
<a name="l00270"></a>00270 u2 = (float)<a class="code" href="sampling_8h.html#4d347f21afe7a5bf94d9e8149dfdea00">RadicalInverse</a>((<span class="keywordtype">int</span>)nshot+1, 17);
<a name="l00271"></a>00271 u3 = (float)<a class="code" href="sampling_8h.html#4d347f21afe7a5bf94d9e8149dfdea00">RadicalInverse</a>((<span class="keywordtype">int</span>)nshot+1, 19);
<a name="l00272"></a>00272 }
<a name="l00273"></a>00273 <span class="keywordflow">else</span> {
<a name="l00274"></a>00274 u1 = <a class="code" href="pbrt_8h.html#4f11994534b888fcf650c04b5d61d9d4">RandomFloat</a>();
<a name="l00275"></a>00275 u2 = <a class="code" href="pbrt_8h.html#4f11994534b888fcf650c04b5d61d9d4">RandomFloat</a>();
<a name="l00276"></a>00276 u3 = <a class="code" href="pbrt_8h.html#4f11994534b888fcf650c04b5d61d9d4">RandomFloat</a>();
<a name="l00277"></a>00277 }
<a name="l00278"></a>00278 <a class="code" href="classSpectrum.html">Spectrum</a> fr = photonBSDF-><a class="code" href="classBSDF.html#3498bc3b7484a17abd8429084124a0d4">Sample_f</a>(wo, &wi, u1, u2, u3,
<a name="l00279"></a>00279 &pdf, <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730734897d21389ab0737866047d40e7122">BSDF_ALL</a>, &flags);
<a name="l00280"></a>00280 <span class="keywordflow">if</span> (fr.<a class="code" href="classSpectrum.html#a05b9a07476998192a83fcd015b7619f">Black</a>() || pdf == 0.f)
<a name="l00281"></a>00281 <span class="keywordflow">break</span>;
<a name="l00282"></a>00282 specularPath = (nIntersections == 1 || specularPath) &&
<a name="l00283"></a>00283 ((flags & <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730c94ee1d195ff19883a79d1c08bd773d9">BSDF_SPECULAR</a>) != 0);
<a name="l00284"></a>00284 alpha *= fr * <a class="code" href="geometry_8h.html#0c07ebf9b1454b90d6646a2f89065bb3">AbsDot</a>(wi, photonBSDF-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#1aa044f6c7b053ca460c10b0cf832c14">nn</a>) / pdf;
<a name="l00285"></a>00285 photonRay = <a class="code" href="classRayDifferential.html">RayDifferential</a>(photonIsect.<a class="code" href="structIntersection.html#27a04b9f68291416c4d864f105a7d991">dg</a>.<a class="code" href="structDifferentialGeometry.html#3d5353db1c1a6a93ef6da642d064f46e">p</a>, wi);
<a name="l00286"></a>00286 <span class="comment">// Possibly terminate photon path</span>
<a name="l00287"></a>00287 <span class="keywordflow">if</span> (nIntersections > 3) {
<a name="l00288"></a>00288 <span class="keywordtype">float</span> continueProbability = .5f;
<a name="l00289"></a>00289 <span class="keywordflow">if</span> (<a class="code" href="pbrt_8h.html#4f11994534b888fcf650c04b5d61d9d4">RandomFloat</a>() > continueProbability)
<a name="l00290"></a>00290 <span class="keywordflow">break</span>;
<a name="l00291"></a>00291 alpha /= continueProbability;
<a name="l00292"></a>00292 }
<a name="l00293"></a>00293 }
<a name="l00294"></a>00294 }
<a name="l00295"></a>00295 <a class="code" href="classBSDF.html#ca0e5890e4ef6d5af745234d9fb4d99e">BSDF::FreeAll</a>();
<a name="l00296"></a>00296 }
<a name="l00297"></a>00297 progress.<a class="code" href="structProgressReporter.html#0cba41f20f2cb68ed0f583e54f22cc73">Done</a>(); <span class="comment">// NOBOOK</span>
<a name="l00298"></a>00298 }
<a name="l00299"></a><a class="code" href="classPhotonIntegrator.html#0187b1d5ee5c39649bc0edea115306d7">00299</a> <a class="code" href="classSpectrum.html">Spectrum</a> <a class="code" href="classPhotonIntegrator.html#0187b1d5ee5c39649bc0edea115306d7">PhotonIntegrator::Li</a>(<span class="keyword">const</span> <a class="code" href="classScene.html">Scene</a> *scene,
<a name="l00300"></a>00300 <span class="keyword">const</span> <a class="code" href="classRayDifferential.html">RayDifferential</a> &ray, <span class="keyword">const</span> <a class="code" href="structSample.html">Sample</a> *sample,
<a name="l00301"></a>00301 <span class="keywordtype">float</span> *alpha)<span class="keyword"> const </span>{
<a name="l00302"></a>00302 <span class="comment">// Compute reflected radiance with photon map</span>
<a name="l00303"></a>00303 <a class="code" href="classSpectrum.html">Spectrum</a> L(0.);
<a name="l00304"></a>00304 <a class="code" href="structIntersection.html">Intersection</a> isect;
<a name="l00305"></a>00305 <span class="keywordflow">if</span> (scene-><a class="code" href="classScene.html#36f27fc416cc5b53fe03575e2d15803a">Intersect</a>(ray, &isect)) {
<a name="l00306"></a>00306 <span class="keywordflow">if</span> (alpha) *alpha = 1.;
<a name="l00307"></a>00307 <a class="code" href="classVector.html">Vector</a> wo = -ray.<a class="code" href="classRay.html#5bbfc94e178e0a050b51200acc579069">d</a>;
<a name="l00308"></a>00308 <span class="comment">// Compute emitted light if ray hit an area light source</span>
<a name="l00309"></a>00309 L += isect.<a class="code" href="structIntersection.html#a2f623b7b62e37a4e083fb0118d47fa3">Le</a>(wo);
<a name="l00310"></a>00310 <span class="comment">// Evaluate BSDF at hit point</span>
<a name="l00311"></a>00311 <a class="code" href="classBSDF.html">BSDF</a> *bsdf = isect.<a class="code" href="structIntersection.html#ff18bb39143b49fa340a3697b9c606b5">GetBSDF</a>(ray);
<a name="l00312"></a>00312 <span class="keyword">const</span> <a class="code" href="classPoint.html">Point</a> &p = bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#3d5353db1c1a6a93ef6da642d064f46e">p</a>;
<a name="l00313"></a>00313 <span class="keyword">const</span> <a class="code" href="classNormal.html">Normal</a> &n = bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#1aa044f6c7b053ca460c10b0cf832c14">nn</a>;
<a name="l00314"></a>00314 <span class="comment">// Compute direct lighting for photon map integrator</span>
<a name="l00315"></a>00315 <span class="keywordflow">if</span> (<a class="code" href="classPhotonIntegrator.html#8a3aad58b4663515b13593d4bd992ad3">directWithPhotons</a>)
<a name="l00316"></a>00316 L += <a class="code" href="classPhotonIntegrator.html#043826406cef3a743136fec3ae7d0c1f">LPhoton</a>(<a class="code" href="classPhotonIntegrator.html#8d035fec0e4d3b37e2f1d2dd13c6d46f">directMap</a>, <a class="code" href="classPhotonIntegrator.html#b381d714f5e64926a4d9e75d95f35a28">nDirectPaths</a>, <a class="code" href="classPhotonIntegrator.html#109c50b0e93a3794714f0097067a8d3a">nLookup</a>,
<a name="l00317"></a>00317 bsdf, isect, wo, <a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">maxDistSquared</a>);
<a name="l00318"></a>00318 <span class="keywordflow">else</span>
<a name="l00319"></a>00319 L += <a class="code" href="transport_8cpp.html#b9dc243808fac32535dce9d4c4a29699">UniformSampleAllLights</a>(scene, p, n,
<a name="l00320"></a>00320 wo, bsdf, sample,
<a name="l00321"></a>00321 <a class="code" href="classPhotonIntegrator.html#4013aa21a8ee2546aa99474f25eaa23f">lightSampleOffset</a>, <a class="code" href="classPhotonIntegrator.html#8709a8a6facd8ff4b5f4893b20cd57a2">bsdfSampleOffset</a>,
<a name="l00322"></a>00322 <a class="code" href="classPhotonIntegrator.html#c41ce1a769442e7112e77a189df97cd2">bsdfComponentOffset</a>);
<a name="l00323"></a>00323
<a name="l00324"></a>00324 <span class="comment">// Compute indirect lighting for photon map integrator</span>
<a name="l00325"></a>00325 L += <a class="code" href="classPhotonIntegrator.html#043826406cef3a743136fec3ae7d0c1f">LPhoton</a>(<a class="code" href="classPhotonIntegrator.html#85c50f55232492130ce83f2bbdcb7efe">causticMap</a>, <a class="code" href="classPhotonIntegrator.html#8dea7dd8abb3a05f9b0f63e83dce192c">nCausticPaths</a>, <a class="code" href="classPhotonIntegrator.html#109c50b0e93a3794714f0097067a8d3a">nLookup</a>, bsdf,
<a name="l00326"></a>00326 isect, wo, <a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">maxDistSquared</a>);
<a name="l00327"></a>00327 <span class="keywordflow">if</span> (<a class="code" href="classPhotonIntegrator.html#82815c88dbee65f65bf7ad6cc2913366">finalGather</a>) {
<a name="l00328"></a>00328 <span class="comment">// Do one-bounce final gather for photon map</span>
<a name="l00329"></a>00329 <a class="code" href="classSpectrum.html">Spectrum</a> <a class="code" href="classPhotonIntegrator.html#0187b1d5ee5c39649bc0edea115306d7">Li</a>(0.);
<a name="l00330"></a>00330 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < <a class="code" href="classPhotonIntegrator.html#e7935d00219d736a590ff983d935d03c">gatherSamples</a>; ++i) {
<a name="l00331"></a>00331 <span class="comment">// Sample random direction for final gather ray</span>
<a name="l00332"></a>00332 <a class="code" href="classVector.html">Vector</a> wi;
<a name="l00333"></a>00333 <span class="keywordtype">float</span> u1 = sample-><a class="code" href="structSample.html#8e0e38f3500cced0e381981d0aec7914">twoD</a>[<a class="code" href="classPhotonIntegrator.html#eab686612dd48fec04cbcc28918ff560">gatherSampleOffset</a>][2*i];
<a name="l00334"></a>00334 <span class="keywordtype">float</span> u2 = sample-><a class="code" href="structSample.html#8e0e38f3500cced0e381981d0aec7914">twoD</a>[<a class="code" href="classPhotonIntegrator.html#eab686612dd48fec04cbcc28918ff560">gatherSampleOffset</a>][2*i+1];
<a name="l00335"></a>00335 <span class="keywordtype">float</span> u3 = sample-><a class="code" href="structSample.html#4a1ae5fbae61678e57efaf185a319ceb">oneD</a>[<a class="code" href="classPhotonIntegrator.html#dbf0bf147f2caf1bdeeeced3498e0404">gatherComponentOffset</a>][i];
<a name="l00336"></a>00336 <span class="keywordtype">float</span> pdf;
<a name="l00337"></a>00337 <a class="code" href="classSpectrum.html">Spectrum</a> fr = bsdf-><a class="code" href="classBSDF.html#3498bc3b7484a17abd8429084124a0d4">Sample_f</a>(wo, &wi, u1, u2, u3,
<a name="l00338"></a>00338 &pdf, <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730">BxDFType</a>(<a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730734897d21389ab0737866047d40e7122">BSDF_ALL</a> & (~<a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730c94ee1d195ff19883a79d1c08bd773d9">BSDF_SPECULAR</a>)));
<a name="l00339"></a>00339 <span class="keywordflow">if</span> (fr.<a class="code" href="classSpectrum.html#a05b9a07476998192a83fcd015b7619f">Black</a>() || pdf == 0.f) <span class="keywordflow">continue</span>;
<a name="l00340"></a>00340 <a class="code" href="classRayDifferential.html">RayDifferential</a> bounceRay(p, wi);
<a name="l00341"></a>00341 <span class="keyword">static</span> <a class="code" href="classStatsCounter.html">StatsCounter</a> gatherRays(<span class="stringliteral">"Photon Map"</span>, <span class="comment">// NOBOOK</span>
<a name="l00342"></a>00342 <span class="stringliteral">"Final gather rays traced"</span>); <span class="comment">// NOBOOK</span>
<a name="l00343"></a>00343 ++gatherRays; <span class="comment">// NOBOOK</span>
<a name="l00344"></a>00344 <a class="code" href="structIntersection.html">Intersection</a> gatherIsect;
<a name="l00345"></a>00345 <span class="keywordflow">if</span> (scene-><a class="code" href="classScene.html#36f27fc416cc5b53fe03575e2d15803a">Intersect</a>(bounceRay, &gatherIsect)) {
<a name="l00346"></a>00346 <span class="comment">// Compute exitant radiance at final gather intersection</span>
<a name="l00347"></a>00347 <a class="code" href="classBSDF.html">BSDF</a> *gatherBSDF = gatherIsect.<a class="code" href="structIntersection.html#ff18bb39143b49fa340a3697b9c606b5">GetBSDF</a>(bounceRay);
<a name="l00348"></a>00348 <a class="code" href="classVector.html">Vector</a> bounceWo = -bounceRay.<a class="code" href="classRay.html#5bbfc94e178e0a050b51200acc579069">d</a>;
<a name="l00349"></a>00349 <a class="code" href="classSpectrum.html">Spectrum</a> Lindir =
<a name="l00350"></a>00350 <a class="code" href="classPhotonIntegrator.html#043826406cef3a743136fec3ae7d0c1f">LPhoton</a>(<a class="code" href="classPhotonIntegrator.html#8d035fec0e4d3b37e2f1d2dd13c6d46f">directMap</a>, <a class="code" href="classPhotonIntegrator.html#b381d714f5e64926a4d9e75d95f35a28">nDirectPaths</a>, <a class="code" href="classPhotonIntegrator.html#109c50b0e93a3794714f0097067a8d3a">nLookup</a>,
<a name="l00351"></a>00351 gatherBSDF, gatherIsect, bounceWo, <a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">maxDistSquared</a>) +
<a name="l00352"></a>00352 <a class="code" href="classPhotonIntegrator.html#043826406cef3a743136fec3ae7d0c1f">LPhoton</a>(<a class="code" href="classPhotonIntegrator.html#56063efc17dae052295962d1f8a33f02">indirectMap</a>, <a class="code" href="classPhotonIntegrator.html#904efc498424ac1a613bf44451386ddb">nIndirectPaths</a>, <a class="code" href="classPhotonIntegrator.html#109c50b0e93a3794714f0097067a8d3a">nLookup</a>,
<a name="l00353"></a>00353 gatherBSDF, gatherIsect, bounceWo, <a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">maxDistSquared</a>) +
<a name="l00354"></a>00354 <a class="code" href="classPhotonIntegrator.html#043826406cef3a743136fec3ae7d0c1f">LPhoton</a>(<a class="code" href="classPhotonIntegrator.html#85c50f55232492130ce83f2bbdcb7efe">causticMap</a>, <a class="code" href="classPhotonIntegrator.html#8dea7dd8abb3a05f9b0f63e83dce192c">nCausticPaths</a>, <a class="code" href="classPhotonIntegrator.html#109c50b0e93a3794714f0097067a8d3a">nLookup</a>,
<a name="l00355"></a>00355 gatherBSDF, gatherIsect, bounceWo, <a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">maxDistSquared</a>);
<a name="l00356"></a>00356 Lindir *= scene-><a class="code" href="classScene.html#c80ef18b12e54a64a809de677aada2e9">Transmittance</a>(bounceRay);
<a name="l00357"></a>00357 Li += fr * Lindir * <a class="code" href="geometry_8h.html#0c07ebf9b1454b90d6646a2f89065bb3">AbsDot</a>(wi, n) / pdf;
<a name="l00358"></a>00358 }
<a name="l00359"></a>00359 }
<a name="l00360"></a>00360 L += Li / float(gatherSamples);
<a name="l00361"></a>00361 }
<a name="l00362"></a>00362 <span class="keywordflow">else</span>
<a name="l00363"></a>00363 L += <a class="code" href="classPhotonIntegrator.html#043826406cef3a743136fec3ae7d0c1f">LPhoton</a>(<a class="code" href="classPhotonIntegrator.html#56063efc17dae052295962d1f8a33f02">indirectMap</a>, <a class="code" href="classPhotonIntegrator.html#904efc498424ac1a613bf44451386ddb">nIndirectPaths</a>, <a class="code" href="classPhotonIntegrator.html#109c50b0e93a3794714f0097067a8d3a">nLookup</a>,
<a name="l00364"></a>00364 bsdf, isect, wo, <a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">maxDistSquared</a>);
<a name="l00365"></a>00365 <span class="keywordflow">if</span> (<a class="code" href="classPhotonIntegrator.html#269bcd41069dffb655a52f1e99effd81">specularDepth</a>++ < <a class="code" href="classPhotonIntegrator.html#81b311d7c1cc3777af0c931c7378c5e1">maxSpecularDepth</a>) {
<a name="l00366"></a>00366 <a class="code" href="classVector.html">Vector</a> wi;
<a name="l00367"></a>00367 <span class="comment">// Trace rays for specular reflection and refraction</span>
<a name="l00368"></a>00368 <a class="code" href="classSpectrum.html">Spectrum</a> f = bsdf-><a class="code" href="classBSDF.html#3498bc3b7484a17abd8429084124a0d4">Sample_f</a>(wo, &wi,
<a name="l00369"></a>00369 <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730">BxDFType</a>(<a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e6697304331da0ab7ddceadcfffa81ecf70577e">BSDF_REFLECTION</a> | <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730c94ee1d195ff19883a79d1c08bd773d9">BSDF_SPECULAR</a>));
<a name="l00370"></a>00370 <span class="keywordflow">if</span> (!f.<a class="code" href="classSpectrum.html#a05b9a07476998192a83fcd015b7619f">Black</a>()) {
<a name="l00371"></a>00371 <span class="comment">// Compute ray differential _rd_ for specular reflection</span>
<a name="l00372"></a>00372 <a class="code" href="classRayDifferential.html">RayDifferential</a> rd(p, wi);
<a name="l00373"></a>00373 rd.<a class="code" href="classRayDifferential.html#87b02390087bc229067e219becef4889">hasDifferentials</a> = <span class="keyword">true</span>;
<a name="l00374"></a>00374 rd.<a class="code" href="classRayDifferential.html#15359147d3814d4e592f005e1ae7ef64">rx</a>.<a class="code" href="classRay.html#1014d000992e8ac3b92f150ad2a5cffe">o</a> = p + isect.<a class="code" href="structIntersection.html#27a04b9f68291416c4d864f105a7d991">dg</a>.<a class="code" href="structDifferentialGeometry.html#307387af96b1b7a98358ea448114d697">dpdx</a>;
<a name="l00375"></a>00375 rd.<a class="code" href="classRayDifferential.html#a6ab98cac3bffedb13f3c74f0e13f3b4">ry</a>.<a class="code" href="classRay.html#1014d000992e8ac3b92f150ad2a5cffe">o</a> = p + isect.<a class="code" href="structIntersection.html#27a04b9f68291416c4d864f105a7d991">dg</a>.<a class="code" href="structDifferentialGeometry.html#d3e6794a920835d56713b3659437fc00">dpdy</a>;
<a name="l00376"></a>00376 <span class="comment">// Compute differential reflected directions</span>
<a name="l00377"></a>00377 <a class="code" href="classNormal.html">Normal</a> dndx = bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#f9daf909200f1e446924641fe27029b0">dndu</a> * bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#ee263cfa99de799c049e33b552ff0b82">dudx</a> +
<a name="l00378"></a>00378 bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#cbcc594e0fff4bc1bf44d82e42cc6390">dndv</a> * bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#f0d770bd2370babb99b4eda972a757e2">dvdx</a>;
<a name="l00379"></a>00379 <a class="code" href="classNormal.html">Normal</a> dndy = bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#f9daf909200f1e446924641fe27029b0">dndu</a> * bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#57f8e45c2aa405802f25f1921ba27edd">dudy</a> +
<a name="l00380"></a>00380 bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#cbcc594e0fff4bc1bf44d82e42cc6390">dndv</a> * bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#7343b4a399c5001c92fad44696060142">dvdy</a>;
<a name="l00381"></a>00381 <a class="code" href="classVector.html">Vector</a> dwodx = -ray.<a class="code" href="classRayDifferential.html#15359147d3814d4e592f005e1ae7ef64">rx</a>.<a class="code" href="classRay.html#5bbfc94e178e0a050b51200acc579069">d</a> - wo, dwody = -ray.<a class="code" href="classRayDifferential.html#a6ab98cac3bffedb13f3c74f0e13f3b4">ry</a>.<a class="code" href="classRay.html#5bbfc94e178e0a050b51200acc579069">d</a> - wo;
<a name="l00382"></a>00382 <span class="keywordtype">float</span> dDNdx = <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(dwodx, n) + <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(wo, dndx);
<a name="l00383"></a>00383 <span class="keywordtype">float</span> dDNdy = <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(dwody, n) + <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(wo, dndy);
<a name="l00384"></a>00384 rd.<a class="code" href="classRayDifferential.html#15359147d3814d4e592f005e1ae7ef64">rx</a>.<a class="code" href="classRay.html#5bbfc94e178e0a050b51200acc579069">d</a> = wi -
<a name="l00385"></a>00385 dwodx + 2 * <a class="code" href="classVector.html">Vector</a>(<a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(wo, n) * dndx +
<a name="l00386"></a>00386 dDNdx * n);
<a name="l00387"></a>00387 rd.<a class="code" href="classRayDifferential.html#a6ab98cac3bffedb13f3c74f0e13f3b4">ry</a>.<a class="code" href="classRay.html#5bbfc94e178e0a050b51200acc579069">d</a> = wi -
<a name="l00388"></a>00388 dwody + 2 * Vector(<a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(wo, n) * dndy +
<a name="l00389"></a>00389 dDNdy * n);
<a name="l00390"></a>00390 L += scene-><a class="code" href="classScene.html#79235a24b9d34c5bd08b88f11da4cfb0">Li</a>(rd, sample) * f * <a class="code" href="geometry_8h.html#0c07ebf9b1454b90d6646a2f89065bb3">AbsDot</a>(wi, n);
<a name="l00391"></a>00391 }
<a name="l00392"></a>00392 f = bsdf-><a class="code" href="classBSDF.html#3498bc3b7484a17abd8429084124a0d4">Sample_f</a>(wo, &wi,
<a name="l00393"></a>00393 <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730">BxDFType</a>(<a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730806674394a395d5dc6383956e4f2733f">BSDF_TRANSMISSION</a> | <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730c94ee1d195ff19883a79d1c08bd773d9">BSDF_SPECULAR</a>));
<a name="l00394"></a>00394 <span class="keywordflow">if</span> (!f.<a class="code" href="classSpectrum.html#a05b9a07476998192a83fcd015b7619f">Black</a>()) {
<a name="l00395"></a>00395 <span class="comment">// Compute ray differential _rd_ for specular transmission</span>
<a name="l00396"></a>00396 <a class="code" href="classRayDifferential.html">RayDifferential</a> rd(p, wi);
<a name="l00397"></a>00397 rd.<a class="code" href="classRayDifferential.html#87b02390087bc229067e219becef4889">hasDifferentials</a> = <span class="keyword">true</span>;
<a name="l00398"></a>00398 rd.<a class="code" href="classRayDifferential.html#15359147d3814d4e592f005e1ae7ef64">rx</a>.<a class="code" href="classRay.html#1014d000992e8ac3b92f150ad2a5cffe">o</a> = p + isect.<a class="code" href="structIntersection.html#27a04b9f68291416c4d864f105a7d991">dg</a>.<a class="code" href="structDifferentialGeometry.html#307387af96b1b7a98358ea448114d697">dpdx</a>;
<a name="l00399"></a>00399 rd.<a class="code" href="classRayDifferential.html#a6ab98cac3bffedb13f3c74f0e13f3b4">ry</a>.<a class="code" href="classRay.html#1014d000992e8ac3b92f150ad2a5cffe">o</a> = p + isect.<a class="code" href="structIntersection.html#27a04b9f68291416c4d864f105a7d991">dg</a>.<a class="code" href="structDifferentialGeometry.html#d3e6794a920835d56713b3659437fc00">dpdy</a>;
<a name="l00400"></a>00400
<a name="l00401"></a>00401 <span class="keywordtype">float</span> eta = bsdf-><a class="code" href="classBSDF.html#1ce3e1bc653569c466bba6ca6666f419">eta</a>;
<a name="l00402"></a>00402 <a class="code" href="classVector.html">Vector</a> w = -wo;
<a name="l00403"></a>00403 <span class="keywordflow">if</span> (<a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(wo, n) < 0) eta = 1.f / eta;
<a name="l00404"></a>00404
<a name="l00405"></a>00405 <a class="code" href="classNormal.html">Normal</a> dndx = bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#f9daf909200f1e446924641fe27029b0">dndu</a> * bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#ee263cfa99de799c049e33b552ff0b82">dudx</a> + bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#cbcc594e0fff4bc1bf44d82e42cc6390">dndv</a> * bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#f0d770bd2370babb99b4eda972a757e2">dvdx</a>;
<a name="l00406"></a>00406 <a class="code" href="classNormal.html">Normal</a> dndy = bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#f9daf909200f1e446924641fe27029b0">dndu</a> * bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#57f8e45c2aa405802f25f1921ba27edd">dudy</a> + bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#cbcc594e0fff4bc1bf44d82e42cc6390">dndv</a> * bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#7343b4a399c5001c92fad44696060142">dvdy</a>;
<a name="l00407"></a>00407
<a name="l00408"></a>00408 <a class="code" href="classVector.html">Vector</a> dwodx = -ray.<a class="code" href="classRayDifferential.html#15359147d3814d4e592f005e1ae7ef64">rx</a>.<a class="code" href="classRay.html#5bbfc94e178e0a050b51200acc579069">d</a> - wo, dwody = -ray.<a class="code" href="classRayDifferential.html#a6ab98cac3bffedb13f3c74f0e13f3b4">ry</a>.<a class="code" href="classRay.html#5bbfc94e178e0a050b51200acc579069">d</a> - wo;
<a name="l00409"></a>00409 <span class="keywordtype">float</span> dDNdx = <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(dwodx, n) + <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(wo, dndx);
<a name="l00410"></a>00410 <span class="keywordtype">float</span> dDNdy = <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(dwody, n) + <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(wo, dndy);
<a name="l00411"></a>00411
<a name="l00412"></a>00412 <span class="keywordtype">float</span> mu = eta * <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(w, n) - <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(wi, n);
<a name="l00413"></a>00413 <span class="keywordtype">float</span> dmudx = (eta - (eta*eta*<a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(w,n))/<a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(wi, n)) * dDNdx;
<a name="l00414"></a>00414 <span class="keywordtype">float</span> dmudy = (eta - (eta*eta*<a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(w,n))/<a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(wi, n)) * dDNdy;
<a name="l00415"></a>00415
<a name="l00416"></a>00416 rd.<a class="code" href="classRayDifferential.html#15359147d3814d4e592f005e1ae7ef64">rx</a>.<a class="code" href="classRay.html#5bbfc94e178e0a050b51200acc579069">d</a> = wi + eta * dwodx - <a class="code" href="classVector.html">Vector</a>(mu * dndx + dmudx * n);
<a name="l00417"></a>00417 rd.<a class="code" href="classRayDifferential.html#a6ab98cac3bffedb13f3c74f0e13f3b4">ry</a>.<a class="code" href="classRay.html#5bbfc94e178e0a050b51200acc579069">d</a> = wi + eta * dwody - Vector(mu * dndy + dmudy * n);
<a name="l00418"></a>00418 L += scene-><a class="code" href="classScene.html#79235a24b9d34c5bd08b88f11da4cfb0">Li</a>(rd, sample) * f * <a class="code" href="geometry_8h.html#0c07ebf9b1454b90d6646a2f89065bb3">AbsDot</a>(wi, n);
<a name="l00419"></a>00419 }
<a name="l00420"></a>00420 }
<a name="l00421"></a>00421 --<a class="code" href="classPhotonIntegrator.html#269bcd41069dffb655a52f1e99effd81">specularDepth</a>;
<a name="l00422"></a>00422 }
<a name="l00423"></a>00423 <span class="keywordflow">else</span> {
<a name="l00424"></a>00424 <span class="comment">// Handle ray with no intersection</span>
<a name="l00425"></a>00425 <span class="keywordflow">if</span> (alpha) *alpha = 0.;
<a name="l00426"></a>00426 <span class="keywordflow">for</span> (<a class="code" href="pbrt_8h.html#c319c165d52643e43249fe003e18bdf3">u_int</a> i = 0; i < scene-><a class="code" href="classScene.html#546553c8f864fd2aa709ad95a1d5ecc9">lights</a>.size(); ++i)
<a name="l00427"></a>00427 L += scene-><a class="code" href="classScene.html#546553c8f864fd2aa709ad95a1d5ecc9">lights</a>[i]->Le(ray);
<a name="l00428"></a>00428 <span class="keywordflow">if</span> (alpha && !L.<a class="code" href="classSpectrum.html#a05b9a07476998192a83fcd015b7619f">Black</a>()) *alpha = 1.;
<a name="l00429"></a>00429 <span class="keywordflow">return</span> L;
<a name="l00430"></a>00430 }
<a name="l00431"></a>00431 <span class="keywordflow">return</span> L;
<a name="l00432"></a>00432 }
<a name="l00433"></a><a class="code" href="classPhotonIntegrator.html#043826406cef3a743136fec3ae7d0c1f">00433</a> <a class="code" href="classSpectrum.html">Spectrum</a> <a class="code" href="classPhotonIntegrator.html#043826406cef3a743136fec3ae7d0c1f">PhotonIntegrator::LPhoton</a>(
<a name="l00434"></a>00434 <a class="code" href="classKdTree.html">KdTree<Photon, PhotonProcess></a> *map,
<a name="l00435"></a>00435 <span class="keywordtype">int</span> nPaths, <span class="keywordtype">int</span> <a class="code" href="classPhotonIntegrator.html#109c50b0e93a3794714f0097067a8d3a">nLookup</a>, <a class="code" href="classBSDF.html">BSDF</a> *bsdf,
<a name="l00436"></a>00436 <span class="keyword">const</span> <a class="code" href="structIntersection.html">Intersection</a> &isect, <span class="keyword">const</span> <a class="code" href="classVector.html">Vector</a> &wo,
<a name="l00437"></a>00437 <span class="keywordtype">float</span> <a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">maxDistSquared</a>) {
<a name="l00438"></a>00438 <a class="code" href="classSpectrum.html">Spectrum</a> L(0.);
<a name="l00439"></a>00439 <span class="keywordflow">if</span> (!map) <span class="keywordflow">return</span> L;
<a name="l00440"></a>00440 <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730">BxDFType</a> nonSpecular = <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730">BxDFType</a>(<a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e6697304331da0ab7ddceadcfffa81ecf70577e">BSDF_REFLECTION</a> |
<a name="l00441"></a>00441 <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730806674394a395d5dc6383956e4f2733f">BSDF_TRANSMISSION</a> | <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730f9e3fbf437624bc9cbe69860ff6c7b80">BSDF_DIFFUSE</a> | <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e6697308ddc5e83718e553544ef1f3b0aa1329b">BSDF_GLOSSY</a>);
<a name="l00442"></a>00442 <span class="keywordflow">if</span> (bsdf-><a class="code" href="classBSDF.html#e6d4c9a1826621a887a4ccd7fa7b5222">NumComponents</a>(nonSpecular) == 0)
<a name="l00443"></a>00443 <span class="keywordflow">return</span> L;
<a name="l00444"></a>00444 <span class="keyword">static</span> <a class="code" href="classStatsCounter.html">StatsCounter</a> lookups(<span class="stringliteral">"Photon Map"</span>, <span class="stringliteral">"Total lookups"</span>); <span class="comment">// NOBOOK</span>
<a name="l00445"></a>00445 <span class="comment">// Initialize _PhotonProcess_ object, _proc_, for photon map lookups</span>
<a name="l00446"></a>00446 <a class="code" href="structPhotonProcess.html">PhotonProcess</a> proc(nLookup, isect.<a class="code" href="structIntersection.html#27a04b9f68291416c4d864f105a7d991">dg</a>.<a class="code" href="structDifferentialGeometry.html#3d5353db1c1a6a93ef6da642d064f46e">p</a>);
<a name="l00447"></a>00447 proc.<a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a> =
<a name="l00448"></a>00448 (<a class="code" href="structClosePhoton.html">ClosePhoton</a> *)alloca(nLookup * <span class="keyword">sizeof</span>(<a class="code" href="structClosePhoton.html">ClosePhoton</a>));
<a name="l00449"></a>00449 <span class="comment">// Do photon map lookup</span>
<a name="l00450"></a>00450 ++lookups; <span class="comment">// NOBOOK</span>
<a name="l00451"></a>00451 map-><a class="code" href="classKdTree.html#e60bcd92fb2446e0e7859f488fa6cb23">Lookup</a>(isect.<a class="code" href="structIntersection.html#27a04b9f68291416c4d864f105a7d991">dg</a>.<a class="code" href="structDifferentialGeometry.html#3d5353db1c1a6a93ef6da642d064f46e">p</a>, proc, maxDistSquared);
<a name="l00452"></a>00452 <span class="comment">// Accumulate light from nearby photons</span>
<a name="l00453"></a>00453 <span class="keyword">static</span> <a class="code" href="classStatsRatio.html">StatsRatio</a> foundRate(<span class="stringliteral">"Photon Map"</span>, <span class="stringliteral">"Photons found per lookup"</span>); <span class="comment">// NOBOOK</span>
<a name="l00454"></a>00454 foundRate.<a class="code" href="classStatsRatio.html#c0530f7ffbb92fa6f736767f0217ed51">Add</a>(proc.<a class="code" href="structPhotonProcess.html#8d8f89eaffea3032799d1cd4587ac9e2">foundPhotons</a>, 1); <span class="comment">// NOBOOK</span>
<a name="l00455"></a>00455 <span class="keywordtype">float</span> scale = 1.f / (float(nPaths) * maxDistSquared * <a class="code" href="pbrt_8h.html#e71449b1cc6e6250b91f539153a7a0d3">M_PI</a>);
<a name="l00456"></a>00456 <span class="comment">// Estimate reflected light from photons</span>
<a name="l00457"></a>00457 <a class="code" href="structClosePhoton.html">ClosePhoton</a> *photons = proc.<a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>;
<a name="l00458"></a>00458 <span class="keywordtype">int</span> nFound = proc.<a class="code" href="structPhotonProcess.html#8d8f89eaffea3032799d1cd4587ac9e2">foundPhotons</a>;
<a name="l00459"></a>00459 <a class="code" href="classNormal.html">Normal</a> Nf = <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(wo, bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#1aa044f6c7b053ca460c10b0cf832c14">nn</a>) < 0 ? -bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#1aa044f6c7b053ca460c10b0cf832c14">nn</a> :
<a name="l00460"></a>00460 bsdf-><a class="code" href="classBSDF.html#4fbebe2038bb049c50deba997a497f2d">dgShading</a>.<a class="code" href="structDifferentialGeometry.html#1aa044f6c7b053ca460c10b0cf832c14">nn</a>;
<a name="l00461"></a>00461 <span class="keywordflow">if</span> (bsdf-><a class="code" href="classBSDF.html#e6d4c9a1826621a887a4ccd7fa7b5222">NumComponents</a>(<a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730">BxDFType</a>(<a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e6697304331da0ab7ddceadcfffa81ecf70577e">BSDF_REFLECTION</a> |
<a name="l00462"></a>00462 <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730806674394a395d5dc6383956e4f2733f">BSDF_TRANSMISSION</a> | <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e6697308ddc5e83718e553544ef1f3b0aa1329b">BSDF_GLOSSY</a>)) > 0) {
<a name="l00463"></a>00463 <span class="comment">// Compute exitant radiance from photons for glossy surface</span>
<a name="l00464"></a>00464 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < nFound; ++i) {
<a name="l00465"></a>00465 <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730">BxDFType</a> flag = <a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(Nf, photons[i].photon->wi) > 0.f ?
<a name="l00466"></a>00466 <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730e6a000f39386b2fb56535cb4999e3fea">BSDF_ALL_REFLECTION</a> : <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730683aea7cc8bd9b61aa4ea1f48aa8867d">BSDF_ALL_TRANSMISSION</a>;
<a name="l00467"></a>00467 L += bsdf-><a class="code" href="classBSDF.html#137c0efa679347a2787b366effdeeb50">f</a>(wo, photons[i].photon->wi, flag) *
<a name="l00468"></a>00468 (scale * photons[i].<a class="code" href="structClosePhoton.html#5fa7f65d8cefe4b33324c636cc7e682d">photon</a>-><a class="code" href="structPhoton.html#621db8918d36d1da824751226522e0bd">alpha</a>);
<a name="l00469"></a>00469 }
<a name="l00470"></a>00470 }
<a name="l00471"></a>00471 <span class="keywordflow">else</span> {
<a name="l00472"></a>00472 <span class="comment">// Compute exitant radiance from photons for diffuse surface</span>
<a name="l00473"></a>00473 <a class="code" href="classSpectrum.html">Spectrum</a> Lr(0.), Lt(0.);
<a name="l00474"></a>00474 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < nFound; ++i)
<a name="l00475"></a>00475 <span class="keywordflow">if</span> (<a class="code" href="geometry_8h.html#ad0d36688d190693f70a5c9ef9342914">Dot</a>(Nf, photons[i].photon->wi) > 0.f)
<a name="l00476"></a>00476 Lr += photons[i].<a class="code" href="structClosePhoton.html#5fa7f65d8cefe4b33324c636cc7e682d">photon</a>-><a class="code" href="structPhoton.html#621db8918d36d1da824751226522e0bd">alpha</a>;
<a name="l00477"></a>00477 <span class="keywordflow">else</span>
<a name="l00478"></a>00478 Lt += photons[i].<a class="code" href="structClosePhoton.html#5fa7f65d8cefe4b33324c636cc7e682d">photon</a>-><a class="code" href="structPhoton.html#621db8918d36d1da824751226522e0bd">alpha</a>;
<a name="l00479"></a>00479 L += (scale * <a class="code" href="pbrt_8h.html#ebad45bfa06a5d66805c5813fbc59f4b">INV_PI</a>) * (Lr * bsdf-><a class="code" href="classBSDF.html#0aa3132935c2c62d824b3bd45f6939d9">rho</a>(wo, <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730e6a000f39386b2fb56535cb4999e3fea">BSDF_ALL_REFLECTION</a>) +
<a name="l00480"></a>00480 Lt * bsdf-><a class="code" href="classBSDF.html#0aa3132935c2c62d824b3bd45f6939d9">rho</a>(wo, <a class="code" href="reflection_8h.html#0ab5fa7d70a51348af4188bf1e669730683aea7cc8bd9b61aa4ea1f48aa8867d">BSDF_ALL_TRANSMISSION</a>));
<a name="l00481"></a>00481 }
<a name="l00482"></a>00482 <span class="keywordflow">return</span> L;
<a name="l00483"></a>00483 }
<a name="l00484"></a>00484 <a class="code" href="structPhotonProcess.html#a13db99c30b2fd91445827345393b295">PhotonProcess::PhotonProcess</a>(<a class="code" href="pbrt_8h.html#c319c165d52643e43249fe003e18bdf3">u_int</a> mp, <span class="keyword">const</span> <a class="code" href="classPoint.html">Point</a> &P)
<a name="l00485"></a>00485 : p(P) {
<a name="l00486"></a>00486 photons = 0;
<a name="l00487"></a>00487 <a class="code" href="classPhotonIntegrator.html#109c50b0e93a3794714f0097067a8d3a">nLookup</a> = mp;
<a name="l00488"></a>00488 foundPhotons = 0;
<a name="l00489"></a>00489 }
<a name="l00490"></a>00490 <span class="keywordtype">void</span> <a class="code" href="structPhotonProcess.html#063ad32af5b764ffc566778d03c26c59">PhotonProcess::operator()</a>(<span class="keyword">const</span> <a class="code" href="structPhoton.html">Photon</a> &photon,
<a name="l00491"></a>00491 <span class="keywordtype">float</span> distSquared, <span class="keywordtype">float</span> &<a class="code" href="classPhotonIntegrator.html#1bc62d7c4651b84f8683ec3f6d4792f6">maxDistSquared</a>)<span class="keyword"> const </span>{
<a name="l00492"></a>00492 <span class="keyword">static</span> <a class="code" href="classStatsPercentage.html">StatsPercentage</a> discarded(<span class="stringliteral">"Photon Map"</span>, <span class="stringliteral">"Discarded photons"</span>); <span class="comment">// NOBOOK</span>
<a name="l00493"></a>00493 discarded.Add(0, 1); <span class="comment">// NOBOOK</span>
<a name="l00494"></a>00494 <span class="keywordflow">if</span> (<a class="code" href="structPhotonProcess.html#8d8f89eaffea3032799d1cd4587ac9e2">foundPhotons</a> < <a class="code" href="structPhotonProcess.html#5abce4cbd14d9f3e230a5f4d24b590ed">nLookup</a>) {
<a name="l00495"></a>00495 <span class="comment">// Add photon to unordered array of photons</span>
<a name="l00496"></a>00496 <a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>[<a class="code" href="structPhotonProcess.html#8d8f89eaffea3032799d1cd4587ac9e2">foundPhotons</a>++] = <a class="code" href="structClosePhoton.html">ClosePhoton</a>(&photon, distSquared);
<a name="l00497"></a>00497 <span class="keywordflow">if</span> (<a class="code" href="structPhotonProcess.html#8d8f89eaffea3032799d1cd4587ac9e2">foundPhotons</a> == <a class="code" href="structPhotonProcess.html#5abce4cbd14d9f3e230a5f4d24b590ed">nLookup</a>) {
<a name="l00498"></a>00498 std::make_heap(&<a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>[0], &<a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>[<a class="code" href="structPhotonProcess.html#5abce4cbd14d9f3e230a5f4d24b590ed">nLookup</a>]);
<a name="l00499"></a>00499 maxDistSquared = <a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>[0].<a class="code" href="structClosePhoton.html#0a204e03ad7c91dbd2e1dcf949282c7e">distanceSquared</a>;
<a name="l00500"></a>00500 }
<a name="l00501"></a>00501 }
<a name="l00502"></a>00502 <span class="keywordflow">else</span> {
<a name="l00503"></a>00503 <span class="comment">// Remove most distant photon from heap and add new photon</span>
<a name="l00504"></a>00504 discarded.Add(1, 0); <span class="comment">// NOBOOK</span>
<a name="l00505"></a>00505 std::pop_heap(&<a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>[0], &<a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>[<a class="code" href="structPhotonProcess.html#5abce4cbd14d9f3e230a5f4d24b590ed">nLookup</a>]);
<a name="l00506"></a>00506 <a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>[<a class="code" href="structPhotonProcess.html#5abce4cbd14d9f3e230a5f4d24b590ed">nLookup</a>-1] = <a class="code" href="structClosePhoton.html">ClosePhoton</a>(&photon, distSquared);
<a name="l00507"></a>00507 std::push_heap(&<a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>[0], &<a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>[<a class="code" href="structPhotonProcess.html#5abce4cbd14d9f3e230a5f4d24b590ed">nLookup</a>]);
<a name="l00508"></a>00508 maxDistSquared = <a class="code" href="structPhotonProcess.html#7aa68eb6ab57654bb21ecf9b9c8090c0">photons</a>[0].<a class="code" href="structClosePhoton.html#0a204e03ad7c91dbd2e1dcf949282c7e">distanceSquared</a>;
<a name="l00509"></a>00509 }
<a name="l00510"></a>00510 }
<a name="l00511"></a><a class="code" href="photonmap_8cpp.html#292dab5329893d80187ce895221b3e6d">00511</a> <span class="keyword">extern</span> <span class="stringliteral">"C"</span> <a class="code" href="pbrt_8h.html#808e08638be3cba36e36759e5b150de0">DLLEXPORT</a> <a class="code" href="classSurfaceIntegrator.html">SurfaceIntegrator</a> *<a class="code" href="bidirectional_8cpp.html#292dab5329893d80187ce895221b3e6d">CreateSurfaceIntegrator</a>(<span class="keyword">const</span> <a class="code" href="classParamSet.html">ParamSet</a> &params) {
<a name="l00512"></a>00512 <span class="keywordtype">int</span> nCaustic = params.<a class="code" href="classParamSet.html#23f24db9c46375e33764910c4fa999d5">FindOneInt</a>(<span class="stringliteral">"causticphotons"</span>, 20000);
<a name="l00513"></a>00513 <span class="keywordtype">int</span> nDirect = params.<a class="code" href="classParamSet.html#23f24db9c46375e33764910c4fa999d5">FindOneInt</a>(<span class="stringliteral">"directphotons"</span>, 100000);
<a name="l00514"></a>00514 <span class="keywordtype">int</span> nIndirect = params.<a class="code" href="classParamSet.html#23f24db9c46375e33764910c4fa999d5">FindOneInt</a>(<span class="stringliteral">"indirectphotons"</span>, 100000);
<a name="l00515"></a>00515 <span class="keywordtype">int</span> nUsed = params.<a class="code" href="classParamSet.html#23f24db9c46375e33764910c4fa999d5">FindOneInt</a>(<span class="stringliteral">"nused"</span>, 50);
<a name="l00516"></a>00516 <span class="keywordtype">int</span> maxDepth = params.<a class="code" href="classParamSet.html#23f24db9c46375e33764910c4fa999d5">FindOneInt</a>(<span class="stringliteral">"maxdepth"</span>, 5);
<a name="l00517"></a>00517 <span class="keywordtype">bool</span> finalGather = params.<a class="code" href="classParamSet.html#3a0bf8f2142200ec23078cde92bd41b4">FindOneBool</a>(<span class="stringliteral">"finalgather"</span>, <span class="keyword">true</span>);
<a name="l00518"></a>00518 <span class="keywordtype">bool</span> directPhotons = params.<a class="code" href="classParamSet.html#3a0bf8f2142200ec23078cde92bd41b4">FindOneBool</a>(<span class="stringliteral">"directwithphotons"</span>, <span class="keyword">false</span>);
<a name="l00519"></a>00519 <span class="keywordtype">int</span> gatherSamples = params.<a class="code" href="classParamSet.html#23f24db9c46375e33764910c4fa999d5">FindOneInt</a>(<span class="stringliteral">"finalgathersamples"</span>, 32);
<a name="l00520"></a>00520 <span class="keywordtype">float</span> maxDist = params.<a class="code" href="classParamSet.html#87143fd8e73a75082179a110d42531a4">FindOneFloat</a>(<span class="stringliteral">"maxdist"</span>, .1f);
<a name="l00521"></a>00521 <span class="keywordflow">return</span> <span class="keyword">new</span> <a class="code" href="classPhotonIntegrator.html">PhotonIntegrator</a>(nCaustic, nDirect, nIndirect,
<a name="l00522"></a>00522 nUsed, maxDepth, maxDist, finalGather, gatherSamples,
<a name="l00523"></a>00523 directPhotons);
<a name="l00524"></a>00524 }
</pre></div></div>
<hr size="1"><address style="text-align: right;"><small>Generated on Mon Jul 20 17:31:53 2009 for pbrt by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.6 </small></address>
</body>
</html>