source: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp @ 2015

Revision 2015, 19.3 KB checked in by bittner, 17 years ago (diff)

pvs efficiency tuning

Line 
1#include "SamplingStrategy.h"
2#include "Ray.h"
3#include "Intersectable.h"
4#include "Preprocessor.h"
5#include "ViewCellsManager.h"
6#include "AxisAlignedBox3.h"
7#include "RssTree.h"
8#include "Mutation.h"
9#include "PerfTimer.h"
10
11namespace GtpVisibilityPreprocessor {
12
13extern PerfTimer pvsTimer;
14
15//HaltonSequence SamplingStrategy::sHalton;
16
17HaltonSequence ObjectBasedDistribution::sHalton;
18HaltonSequence MixtureDistribution::sHalton;
19HaltonSequence GlobalLinesDistribution::sHalton;
20HaltonSequence SpatialBoxBasedDistribution::sHalton;
21HaltonSequence ObjectDirectionBasedDistribution::sHalton;
22HaltonSequence DirectionBasedDistribution::sHalton;
23HaltonSequence HwGlobalLinesDistribution::sHalton;
24
25HaltonSequence ViewCellBasedDistribution::sHalton;
26
27SamplingStrategy::SamplingStrategy(Preprocessor &preprocessor):
28mPreprocessor(preprocessor),
29mRatio(1.0f), 
30mTotalRays(0),
31mTotalContribution(0.0f)
32
33}
34
35
36SamplingStrategy::~SamplingStrategy()
37{
38}
39
40int
41SamplingStrategy::GenerateSamples(const int number,
42                                                                  SimpleRayContainer &rays)
43{
44        SimpleRay ray;
45        int samples = 0;
46        int i = 0;
47        const int maxTries = 20;
48        // tmp changed matt. Q: should one rejected sample
49        // terminate the whole method?
50        for (; i < number; i++)
51          {
52                int j = 0;
53                bool sampleGenerated = false;
54               
55                for (j = 0; !sampleGenerated && (j < maxTries); ++ j)
56                  {
57                        sampleGenerated = GenerateSample(ray);
58                       
59                        if (sampleGenerated)
60                          {             
61                                ++ samples;
62                                rays.push_back(ray);
63                          }
64                  }
65          }
66
67
68       
69
70        return samples;
71}
72
73
74/*********************************************************************/
75/*            Individual sampling strategies implementation          */
76/*********************************************************************/
77
78
79bool ObjectBasedDistribution::GenerateSample(SimpleRay &ray)
80{
81  Vector3 origin, direction;
82 
83  float r[5];
84  sHalton.GetNext(5, r);
85 
86  mPreprocessor.mViewCellsManager->GetViewPoint(origin,
87                                                                                                Vector3(r[2],r[3],r[4]));
88 
89
90  Vector3 point, normal;
91 
92  r[0] *= (float)mPreprocessor.mObjects.size() - 1;
93  const int i = (int)r[0];
94 
95  Intersectable *object = mPreprocessor.mObjects[i];
96 
97  // take the remainder as a parameter over objects surface
98  r[0] -= (float)i;
99 
100  object->GetRandomSurfacePoint(r[0], r[1], point, normal);
101 
102  direction = point - origin;
103 
104  const float c = Magnitude(direction);
105 
106  if (c <= Limits::Small)
107        return false;
108 
109  // $$ jb the pdf is yet not correct for all sampling methods!
110  const float pdf = 1.0f;
111 
112  direction *= 1.0f / c;
113  ray = SimpleRay(origin, direction, OBJECT_BASED_DISTRIBUTION, pdf);
114 
115  return true;
116}
117
118
119bool
120ObjectDirectionBasedDistribution::GenerateSample(SimpleRay &ray)
121{       
122  Vector3 origin, direction;
123
124
125  float r[4];
126  sHalton.GetNext(4, r);
127
128  r[0] *= (float)mPreprocessor.mObjects.size() - 1;
129  const int i = (int)r[0];
130 
131  Intersectable *object = mPreprocessor.mObjects[i];
132 
133  // take the remainder as a parameter over objects surface
134  r[0] -= (float)i;
135
136  Vector3 normal;
137
138  object->GetRandomSurfacePoint(r[0], r[1], origin, normal);
139 
140  direction = Normalize(CosineRandomVector(r[2], r[3], normal));
141 
142  origin += 1e-2f*direction;
143 
144  // $$ jb the pdf is yet not correct for all sampling methods!
145  const float pdf = 1.0f;
146 
147  ray = SimpleRay(origin, direction, OBJECT_DIRECTION_BASED_DISTRIBUTION, pdf);
148 
149  return true;
150}
151
152
153bool DirectionBasedDistribution::GenerateSample(SimpleRay &ray)
154{       
155
156  float r[5];
157  sHalton.GetNext(5, r);
158
159  Vector3 origin, direction;
160  mPreprocessor.mViewCellsManager->GetViewPoint(origin,
161                                                                                                Vector3(r[2],r[3],r[4])
162                                                                                                );
163 
164  direction = UniformRandomVector(r[0], r[1]);
165  const float c = Magnitude(direction);
166 
167  if (c <= Limits::Small)
168        return false;
169 
170  const float pdf = 1.0f;
171 
172  direction *= 1.0f / c;
173  ray = SimpleRay(origin, direction, DIRECTION_BASED_DISTRIBUTION, pdf);
174 
175  return true;
176}
177
178
179bool DirectionBoxBasedDistribution::GenerateSample(SimpleRay &ray)
180{
181        Vector3 origin, direction;
182        mPreprocessor.mViewCellsManager->GetViewPoint(origin);
183
184        const float alpha = RandomValue(0.0f, 2.0f * (float)M_PI);
185        const float beta = RandomValue((float)-M_PI * 0.5f, (float)M_PI * 0.5f);
186       
187        direction = VssRay::GetDirection(alpha, beta);
188       
189        const float c = Magnitude(direction);
190
191        if (c <= Limits::Small)
192                return false;
193
194        const float pdf = 1.0f;
195
196        direction *= 1.0f / c;
197        ray = SimpleRay(origin, direction, DIRECTION_BOX_BASED_DISTRIBUTION, pdf);
198
199        return true;
200}
201
202
203bool SpatialBoxBasedDistribution::GenerateSample(SimpleRay &ray)
204{
205  Vector3 origin, direction;
206
207  float r[6];
208  sHalton.GetNext(6, r);
209  mPreprocessor.mViewCellsManager->GetViewPoint(origin, Vector3(r[0],r[1],r[2]));
210 
211  direction = mPreprocessor.mKdTree->GetBox().GetRandomPoint(Vector3(r[3],
212                                                                                                                                         r[4],
213                                                                                                                                         r[5])
214                                                                                                                                         ) - origin;
215  //cout << "z";
216  const float c = Magnitude(direction);
217 
218  if (c <= Limits::Small)
219        return false;
220 
221  const float pdf = 1.0f;
222 
223  direction *= 1.0f / c;
224  ray = SimpleRay(origin, direction, SPATIAL_BOX_BASED_DISTRIBUTION, pdf);
225 
226  return true;
227}
228
229
230bool ReverseObjectBasedDistribution::GenerateSample(SimpleRay &ray)
231{
232        Vector3 origin, direction;
233
234        mPreprocessor.mViewCellsManager->GetViewPoint(origin);
235
236        Vector3 point;
237        Vector3 normal;
238       
239        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
240
241        Intersectable *object = mPreprocessor.mObjects[i];
242
243        object->GetRandomSurfacePoint(point, normal);
244       
245        direction = origin - point;
246       
247        // $$ jb the pdf is yet not correct for all sampling methods!
248        const float c = Magnitude(direction);
249       
250        if ((c <= Limits::Small) || (DotProd(direction, normal) < 0))
251        {
252                return false;
253        }
254
255        // $$ jb the pdf is yet not correct for all sampling methods!
256        const float pdf = 1.0f;
257        //cout << "p: " << point << " ";
258        direction *= 1.0f / c;
259        // a little offset
260        point += direction * 0.001f;
261
262        ray = SimpleRay(point, direction, REVERSE_OBJECT_BASED_DISTRIBUTION, pdf);
263       
264        return true;
265}
266
267
268bool ViewCellBorderBasedDistribution::GenerateSample(SimpleRay &ray)
269{
270        Vector3 origin, direction;
271
272        ViewCellContainer &viewCells = mPreprocessor.mViewCellsManager->GetViewCells();
273
274        Vector3 point;
275        Vector3 normal, normal2;
276       
277        const int vcIdx = (int)RandomValue(0, (float)viewCells.size() - 0.5f);
278        const int objIdx = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
279
280        Intersectable *object = mPreprocessor.mObjects[objIdx];
281        ViewCell *viewCell = viewCells[vcIdx];
282
283        //cout << "vc: " << vcIdx << endl;
284        //cout << "obj: " << objIdx << endl;
285
286        object->GetRandomSurfacePoint(point, normal);
287        viewCell->GetRandomEdgePoint(origin, normal2);
288
289        direction = point - origin;
290
291        // $$ jb the pdf is yet not correct for all sampling methods!
292        const float c = Magnitude(direction);
293
294        if ((c <= Limits::Small) /*|| (DotProd(direction, normal) < 0)*/)
295        {
296                return false;
297        }
298
299        // $$ jb the pdf is yet not correct for all sampling methods!
300        const float pdf = 1.0f;
301        //cout << "p: " << point << " ";
302        direction *= 1.0f / c;
303        ray = SimpleRay(origin, direction, VIEWCELL_BORDER_BASED_DISTRIBUTION, pdf);
304
305        //cout << "ray: " << ray.mOrigin << " " << ray.mDirection << endl;
306
307        return true;
308}
309
310
311#if 0
312bool ObjectsInteriorDistribution::GenerateSample(SimpleRay &ray)
313{
314        Vector3 origin, direction;
315
316        // get random object
317        const int i = RandomValue(0, mPreprocessor.mObjects.size() - 1);
318
319        const Intersectable *obj = mPreprocessor.mObjects[i];
320
321        // note: if we load the polygons as meshes,
322        // asymtotically every second sample is lost!
323        origin = obj->GetBox().GetRandomPoint();
324
325        // uniformly distributed direction
326        direction = UniformRandomVector();
327
328        const float c = Magnitude(direction);
329
330        if (c <= Limits::Small)
331                return false;
332
333        const float pdf = 1.0f;
334
335        direction *= 1.0f / c;
336        ray = SimpleRay(origin, direction, pdf);
337
338        return true;
339}
340
341#endif
342
343
344bool ReverseViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray)
345{
346        Vector3 origin, direction;
347
348        origin = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
349
350        Vector3 point;
351        Vector3 normal;
352       
353        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
354
355        Intersectable *object = mPreprocessor.mObjects[i];
356
357        object->GetRandomSurfacePoint(point, normal);
358       
359        direction = origin - point;
360       
361        // $$ jb the pdf is yet not correct for all sampling methods!
362        const float c = Magnitude(direction);
363       
364        if ((c <= Limits::Small) || (DotProd(direction, normal) < 0))
365        {
366                return false;
367        }
368
369        // $$ jb the pdf is yet not correct for all sampling methods!
370        const float pdf = 1.0f;
371        //cout << "p: " << point << " ";
372        direction *= 1.0f / c;
373        // a little offset
374        point += direction * 0.001f;
375
376        ray = SimpleRay(point, direction, REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION, pdf);
377       
378        return true;
379}
380
381
382bool ViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray)
383{
384        Vector3 origin, direction;
385
386        origin = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
387
388        Vector3 point;
389        Vector3 normal;
390        //cout << "w";
391        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
392
393        Intersectable *object = mPreprocessor.mObjects[i];
394
395        object->GetRandomSurfacePoint(point, normal);
396        direction = point - origin;
397
398        // $$ jb the pdf is yet not correct for all sampling methods!
399        const float c = Magnitude(direction);
400
401        if (c <= Limits::Small)
402                return false;
403
404        // $$ jb the pdf is yet not correct for all sampling methods!
405        const float pdf = 1.0f;
406       
407        direction *= 1.0f / c;
408
409        // a little offset
410        origin += direction * 0.001f;
411
412        ray = SimpleRay(origin, direction, VIEWSPACE_BORDER_BASED_DISTRIBUTION, pdf);
413
414        return true;
415}
416
417
418bool
419GlobalLinesDistribution::GenerateSample(SimpleRay &ray)
420{
421  Vector3 origin, termination, direction;
422
423  float radius = 0.5f*Magnitude(mPreprocessor.mViewCellsManager->GetViewSpaceBox().Size());
424  Vector3 center = mPreprocessor.mViewCellsManager->GetViewSpaceBox().Center();
425
426  const int tries = 1000;
427  int i;
428  for (i=0; i < tries; i++) {
429        float r[4];
430        sHalton.GetNext(4, r);
431       
432        origin = center + (radius*UniformRandomVector(r[0], r[1]));
433        termination = center + (radius*UniformRandomVector(r[2], r[3]));
434       
435        direction = termination - origin;
436       
437       
438        // $$ jb the pdf is yet not correct for all sampling methods!
439        const float c = Magnitude(direction);
440        if (c <= Limits::Small)
441          return false;
442       
443        direction *= 1.0f / c;
444
445        // check if the ray intersects the view space box
446        static Ray ray;
447        ray.Init(origin, direction, Ray::LOCAL_RAY);   
448       
449        float tmin, tmax;
450        if (mPreprocessor.mViewCellsManager->
451                GetViewSpaceBox().ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))
452          break;
453  }
454 
455  if (i!=tries) {
456        // $$ jb the pdf is yet not correct for all sampling methods!
457        const float pdf = 1.0f;
458       
459       
460        ray = SimpleRay(origin, direction, GLOBAL_LINES_DISTRIBUTION, pdf);
461        ray.mType = Ray::GLOBAL_RAY;
462        return true;
463  }
464 
465  return false;
466}
467
468
469  // has to called before first usage
470void
471MixtureDistribution::Init()
472{
473  for (int i=0; i < mDistributions.size(); i++) {
474        // small non-zero value
475        mDistributions[i]->mRays = 1;
476        mDistributions[i]->mGeneratedRays = 1;
477        // unit contribution per ray
478        if (1 || mDistributions[i]->mType != RSS_BASED_DISTRIBUTION)
479          mDistributions[i]->mContribution = 1.0f;
480        else
481          mDistributions[i]->mContribution = 0.0f;
482  }
483  UpdateRatios();
484}
485
486void
487MixtureDistribution::Reset()
488{
489  for (int i=0; i < mDistributions.size(); i++) {
490        // small non-zero value
491        mDistributions[i]->mTotalRays = 0;
492        // unit contribution per ray
493        mDistributions[i]->mTotalContribution = 0.0f;
494  }
495  UpdateRatios();
496}
497
498// Generate a new sample according to a mixture distribution
499bool
500MixtureDistribution::GenerateSample(SimpleRay &ray)
501{
502  float r;
503  sHalton.GetNext(1, &r);
504  int i;
505  // pickup a distribution
506  for (i=0; i < mDistributions.size()-1; i++)
507        if (r < mDistributions[i]->mRatio)
508          break;
509
510  bool result = mDistributions[i]->GenerateSample(ray);
511
512  if (result)
513        mDistributions[i]->mGeneratedRays++;
514 
515  return result;
516}
517
518  // add contributions of the sample to the strategies
519void
520MixtureDistribution::ComputeContributions(VssRayContainer &vssRays)
521{
522  int i;
523 
524  VssRayContainer::iterator it = vssRays.begin();
525
526  for (i=0; i < mDistributions.size(); i++) {
527        mDistributions[i]->mContribution = 0;
528        mDistributions[i]->mRays = 0;
529  }
530
531  for(; it != vssRays.end(); ++it) {
532        VssRay *ray = *it;
533        for (i=0; i < mDistributions.size()-1; i++) {
534          if (mDistributions[i]->mType == ray->mDistribution)
535                break;
536        }
537 
538        float contribution =
539          mPreprocessor.mViewCellsManager->ComputeSampleContribution(*ray,
540                                                                                                                                 true,
541                                                                                                                                 false);
542
543        mDistributions[i]->mContribution += contribution;
544        mDistributions[i]->mRays ++;
545       
546        mDistributions[i]->mTotalContribution += contribution;
547        mDistributions[i]->mTotalRays ++;
548  }
549
550  pvsTimer.Entry();
551  // resort pvss
552  mPreprocessor.mViewCellsManager->SortViewCellPvs();
553  pvsTimer.Exit();
554 
555  UpdateRatios();
556
557}
558
559void
560MixtureDistribution::UpdateDistributions(VssRayContainer &vssRays)
561{
562  // now update the distributions with all the rays
563  for (int i=0; i < mDistributions.size(); i++) {
564        mDistributions[i]->Update(vssRays);
565  }
566}
567
568#define RAY_CAST_TIME 0.7f
569#define VIEWCELL_CAST_TIME 0.3f
570
571void
572MixtureDistribution::UpdateRatios()
573{
574  // now compute importance (ratio) of all distributions
575  float sum = 0.0f;
576  int i;
577  for (i=0; i < mDistributions.size(); i++) {
578        cout<<i<<": c="<<mDistributions[i]->mContribution<<
579          " rays="<<mDistributions[i]->mRays<<endl;
580        float importance = 0.0f;
581        if (mDistributions[i]->mRays != 0) {
582          //importance = pow(mDistributions[i]->mContribution/mDistributions[i]->mRays, 2);
583          importance = mDistributions[i]->mContribution/
584                (RAY_CAST_TIME*mDistributions[i]->mGeneratedRays +
585                 VIEWCELL_CAST_TIME*mDistributions[i]->mRays);
586        }
587        mDistributions[i]->mRatio = importance;
588        sum += importance;
589  }
590
591  if (sum == 0.0f)
592        sum = Limits::Small;
593 
594  const float minratio = 0.01f;
595 
596  for (i=0; i < mDistributions.size(); i++) {
597        mDistributions[i]->mRatio /= sum;
598        if (mDistributions[i]->mRatio < minratio)
599          mDistributions[i]->mRatio = minratio;
600  }
601
602  // recaluate the sum after clip
603  sum = 0.0f;
604  for (i=0; i < mDistributions.size(); i++)
605        sum += mDistributions[i]->mRatio;
606
607  for (i=0; i < mDistributions.size(); i++)
608        mDistributions[i]->mRatio /= sum;
609 
610  for (i=1; i < mDistributions.size(); i++) {
611        mDistributions[i]->mRatio = mDistributions[i-1]->mRatio + mDistributions[i]->mRatio;
612  }
613 
614  cout<<"ratios: ";
615  float last = 0.0f;
616  for (i=0; i < mDistributions.size(); i++) {
617        cout<<mDistributions[i]->mRatio-last<<" ";
618        last = mDistributions[i]->mRatio;
619  }
620  cout<<endl;
621}
622
623
624
625bool
626MixtureDistribution::Construct(char *str)
627{
628  char *curr = str;
629
630  while (1) {
631        char *e = strchr(curr,'+');
632        if (e!=NULL) {
633          *e=0;
634        }
635       
636        if (strcmp(curr, "rss")==0) {
637          mDistributions.push_back(new RssBasedDistribution(mPreprocessor));
638        } else
639          if (strcmp(curr, "object")==0) {
640                mDistributions.push_back(new ObjectBasedDistribution(mPreprocessor));
641          } else
642                if (strcmp(curr, "spatial")==0) {
643                  mDistributions.push_back(new SpatialBoxBasedDistribution(mPreprocessor));
644                } else
645                  if (strcmp(curr, "global")==0) {
646                        mDistributions.push_back(new GlobalLinesDistribution(mPreprocessor));
647                  } else
648                        if (strcmp(curr, "direction")==0) {
649                          mDistributions.push_back(new DirectionBasedDistribution(mPreprocessor));
650                        } else
651                          if (strcmp(curr, "object_direction")==0) {
652                                mDistributions.push_back(new ObjectDirectionBasedDistribution(mPreprocessor));
653                          } else
654                                if (strcmp(curr, "reverse_object")==0) {
655                                  mDistributions.push_back(new ReverseObjectBasedDistribution(mPreprocessor));
656                                } else
657                                  if (strcmp(curr, "reverse_viewspace_border")==0) {
658                                        mDistributions.push_back(new ReverseViewSpaceBorderBasedDistribution(mPreprocessor));
659                                  } else
660                                        if (strcmp(curr, "mutation")==0) {
661                                          // temp matt: still no mutationstrategy!
662                                          mDistributions.push_back(new MutationBasedDistribution(mPreprocessor));
663                                        }
664       
665       
666        if (e==NULL)
667          break;
668        curr = e+1;
669  }
670
671  Init();
672  return true;
673}
674
675int
676MixtureDistribution::GenerateSamples(const int number,
677                                                                         SimpleRayContainer &rays)
678{
679  for (int i=0; i < mDistributions.size(); i++)
680        mDistributions[i]->mGeneratedRays = 0;
681
682  return SamplingStrategy::GenerateSamples(number, rays);
683}
684
685
686
687bool HwGlobalLinesDistribution::GenerateSample(SimpleRay &ray)
688{
689        Vector3 origin, termination, direction;
690
691        float radius = 0.5f *
692                Magnitude(mPreprocessor.mViewCellsManager->GetViewSpaceBox().Size());
693
694        Vector3 center = mPreprocessor.mViewCellsManager->GetViewSpaceBox().Center();
695
696        const int tries = 1000;
697        int i;
698        for (i=0; i < tries; i++)
699        {
700                float r[2];
701                sHalton.GetNext(2, r);
702
703                origin = center + (radius * UniformRandomVector(r[0], r[1]));
704                termination = center;
705               
706                if (0)
707                {
708                        // add a small offset to provide some more randomness in the sampling
709                        Vector3 offset(Random(radius * 1e-3f),
710                                                   Random(radius * 1e-3f),
711                                                   Random(radius * 1e-3f));
712                        termination += offset;
713                }
714
715                direction = termination - origin;
716
717                // $$ jb the pdf is yet not correct for all sampling methods!
718                const float c = Magnitude(direction);
719
720                if (c <= Limits::Small)
721                        return false;
722
723                direction *= 1.0f / c;
724
725                // check if the ray intersects the view space box
726                static Ray ray;
727                ray.Init(origin, direction, Ray::LOCAL_RAY);   
728
729                float tmin, tmax;
730                if (mPreprocessor.mViewCellsManager->
731                        GetViewSpaceBox().ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))
732                        break;
733        }
734
735        if (i != tries)
736        {
737                // $$ jb the pdf is yet not correct for all sampling methods!
738                const float pdf = 1.0f;
739
740                ray = SimpleRay(origin, direction, HW_GLOBAL_LINES_DISTRIBUTION, pdf);
741                ray.mType = Ray::GLOBAL_RAY;
742                return true;
743        }
744
745        return false;
746}
747
748
749bool ViewCellBasedDistribution::GenerateSample(SimpleRay &ray)
750{
751        Vector3 origin, direction;
752
753        ViewCellContainer &viewCells =
754                mPreprocessor.mViewCellsManager->GetViewCells();
755
756        Vector3 point;
757        Vector3 normal;
758               
759        //Vector normalObj;
760        // float r[1];
761        // sHalton.GetNext(1, r);
762        // const int objIdx = (int)(r[0] * (float)mPreprocessor.mObjects.size() - 1.0f);
763        // Intersectable *object = mPreprocessor.mObjects[objIdx];
764        // object->GetRandomSurfacePoint(point, normal);
765        // cout << "obj: " << objIdx << endl;
766
767        float r[2];
768        sHalton.GetNext(2, r);
769
770        direction = UniformRandomVector(r[0], r[1]);
771        const float c = Magnitude(direction);
772
773    if (c <= Limits::Small)
774                return false;
775
776        direction *= 1.0f / c;
777
778        // get point on view cell surface
779        mViewCell->GetRandomSurfacePoint(origin, normal);
780
781        //direction = point - origin;
782
783        // move a little bit back to avoid piercing through walls
784        // that bound the view cell
785        origin -= 0.01f * normal;
786
787        // $$ jb the pdf is yet not correct for all sampling methods!
788        const float pdf = 1.0f;
789
790        ray = SimpleRay(origin, direction, VIEWCELL_BASED_DISTRIBUTION, pdf);
791
792        //cout << "ray: " << ray.mOrigin << " " << ray.mDirection << endl;
793
794        return true;
795}
796
797
798}
799
800
Note: See TracBrowser for help on using the repository browser.