source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SampleGenerator.cpp @ 3221

Revision 3221, 5.1 KB checked in by mattausch, 16 years ago (diff)

added some statistics stuff, but ssao slower than before (probably because made ssao width and intensity variable and not hardcoded anymore) from >180 frames to < 130 frames!!!

RevLine 
[2853]1#include "SampleGenerator.h"
[2903]2#include "common.h"
[2853]3
[2901]4
[2853]5using namespace std;
[2903]6using namespace CHCDemoEngine;
[2853]7
[2930]8HaltonSequence SphericalSampleGenerator3::sHalton;
9HaltonSequence PoissonDiscSampleGenerator2::sHalton;
10HaltonSequence RandomSampleGenerator2::sHalton;
11HaltonSequence QuadraticDiscSampleGenerator2::sHalton;
[2853]12
[2901]13
[2853]14SampleGenerator::SampleGenerator(int numSamples, float radius):
15mNumSamples(numSamples), mRadius(radius)
16{}
17
18
[2930]19PoissonDiscSampleGenerator2::PoissonDiscSampleGenerator2(int numSamples, float radius):
[2853]20SampleGenerator(numSamples, radius)
21{}
22
23
[2930]24void PoissonDiscSampleGenerator2::Generate(float *samples) const
[2853]25{
[2930]26        // this is a hacky poisson sampling generator which does random dart-throwing on a disc.
27        // as a savety criterium, the min distance requirement is relaxed if we are not
28        // able to place any dart for a number of tries
[2873]29        // the solution is a possion sampling with respect to the adjusted min distance
30        // better solutions have been proposed, i.e., using hierarchical sampling
[3221]31        const int maxTries = 1000;
[2873]32        const float f_reduction = 0.9f;
33
[2903]34        //static HaltonSequence halton;
[2853]35        float r[2];
36
37        // generates poisson distribution on disc
[2930]38        // start with some threshold. best case: all samples lie on the circumference
39        //const float minDist = 2.0f * mRadius / sqrt((float)mNumSamples);
40        const float eps = 0.2f;
41        const float minDist = 2.0f * mRadius * M_PI * (1.0f - eps) / (float)mNumSamples;
42        float sqrMinDist = minDist * minDist;
[2853]43
44        //cout << "minDist before= " << minDist << endl;
[2900]45        Sample2 *s = (Sample2 *)samples;
[2853]46
[2930]47        int totalTries = 0;
48
49        // check if on disc
[2853]50        for (int i = 0; i < mNumSamples; ++ i)
51        {
[2930]52                int tries = 0;
[2853]53
54                // repeat until valid sample was found
55                while (1)
56                {
57                        ++ tries;
58                        ++ totalTries;
59
[2930]60                        // note: should use halton, but seems somewhat broken
61                        //r[0] = RandomValue(.0f, mRadius);
62                        //r[1] = RandomValue(.0f, mRadius);
63                        sHalton.GetNext(2, r);
[2853]64
[2930]65                        // scale to -1 .. 1
[2853]66                        const float rx = r[0] * 2.0f - 1.0f;
67                        const float ry = r[1] * 2.0f - 1.0f;
68
69                        // check if in disk, else exit early
[3103]70                        const float distanceSquared = rx * rx + ry * ry;
71
72                        if ((rx * rx + ry * ry > mRadius * mRadius)
[3162]73                                // also avoid case that sample exactly in center                       
[3103]74                                || (distanceSquared <= 1e-3f)
75                                )
[2853]76                                continue;
77
78                        bool sampleValid = true;
79
80                        // check poisson property
81                        for (int j = 0; ((j < i) && sampleValid); ++ j)
82                        {
83                                const float dist =
[2930]84                                        (s[j].x - rx) * (s[j].x - rx) +
85                                        (s[j].y - ry) * (s[j].y - ry);
[2853]86                       
[2930]87                                if (dist < sqrMinDist)
[2853]88                                        sampleValid = false;
89                        }
90
91                        if (sampleValid)
92                        {
[2900]93                                s[i].x = rx;
94                                s[i].y = ry;
[2853]95                                break;
96                        }
97
[2873]98                        if (tries > maxTries)
[2853]99                        {
[2930]100                                sqrMinDist *= f_reduction;
[2853]101                                tries = 0;
102                        }
103                }
104        }
105
[2930]106        //cout << "minDist after= " << sqrt(sqrMinDist) << " #tries: " << totalTries << endl;
[2898]107}
108
109
[2930]110RandomSampleGenerator2::RandomSampleGenerator2(int numSamples, float radius):
[2898]111SampleGenerator(numSamples, radius)
112{}
113
114
[2930]115void RandomSampleGenerator2::Generate(float *samples) const
[2898]116{
[2900]117        Sample2 *s = (Sample2 *)samples;
118
[2903]119        int numSamples = 0;
[2898]120
[2930]121        float r[2];
122
[2903]123        while (numSamples < mNumSamples)
[2898]124        {
[2930]125                //r[0] = RandomValue(-mRadius, mRadius);
126                //r[1] = RandomValue(-mRadius, mRadius);
127                sHalton.GetNext(2, r);
128               
129                const float rx = r[0] * 2.0f - 1.0f;
130                const float ry = r[1] * 2.0f - 1.0f;
[2898]131
[2903]132                // check if in disk, else exit early
133                if (rx * rx + ry * ry > mRadius * mRadius)
134                        continue;
[2898]135
[2903]136                s[numSamples].x = rx;
137                s[numSamples].y = ry;
[2898]138
[2903]139                ++ numSamples;
140        }
[2899]141}
142
143
[2930]144SphericalSampleGenerator3::SphericalSampleGenerator3(int numSamples, float radius):
[2899]145SampleGenerator(numSamples, radius)
146{}
147
148
[2930]149void SphericalSampleGenerator3::Generate(float *samples) const
[2899]150{
151        float r[2];
[2900]152        Sample3 *s = (Sample3 *)samples;
153
[2899]154        for (int i = 0; i < mNumSamples; ++ i)
155        {
[2903]156                r[0] = RandomValue(0, 1);
157                r[1] = RandomValue(0, 1);
[2930]158
[2903]159                //sHalton.GetNext(2, r);
[2899]160
161                // create stratified samples over sphere
[2900]162                const float theta = 2.0f * acos(sqrt(1.0f - r[0]));
163                const float phi = 2.0f * M_PI * r[1];
[2901]164 
165                s[i].x = mRadius * sin(theta) * cos(phi);
166                s[i].y = mRadius * sin(theta) * sin(phi);
167                s[i].z = mRadius * cos(theta);
168        }
[2930]169}
[2899]170
[2930]171
172QuadraticDiscSampleGenerator2::QuadraticDiscSampleGenerator2(int numSamples, float radius):
173SampleGenerator(numSamples, radius)
174{}
175
176
177void QuadraticDiscSampleGenerator2::Generate(float *samples) const
178{
[2954]179#if 0
[2930]180        float r[2];
181        Sample2 *s = (Sample2 *)samples;
182
183        for (int i = 0; i < mNumSamples; ++ i)
184        {
185                //r[0] = samples[i * 2];
186                //r[1] = samples[i * 2 + 1];
187                sHalton.GetNext(2, r);
188
189                // create samples over disc: the sample density
190                // decreases quadratically with the distance to the origin
191                s[i].x = mRadius * r[1] * sin(2.0f * M_PI * r[0]);
192                s[i].y = mRadius * r[1] * cos(2.0f * M_PI * r[0]);
[2954]193        }
194#else
[2930]195
[2954]196        PoissonDiscSampleGenerator2 poisson(mNumSamples, 1.0f);
197        poisson.Generate(samples);
198
199        Sample2 *s = (Sample2 *)samples;
200
201        // multiply with lenght to get quadratic dependence on the distance
202        for (int i = 0; i < mNumSamples; ++ i)
203        {
[2955]204                Sample2 &spl = s[i];
[2954]205
206                float len = sqrt(spl.x * spl.x + spl.y * spl.y);
207                spl.x *= len * mRadius;
208                spl.y *= len * mRadius;
[2930]209        }
[2954]210#endif
[2853]211}
Note: See TracBrowser for help on using the repository browser.