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
|
#pragma once
#include "SyntopiaCore/Math/Random.h"
#include "SyntopiaCore/Math/Vector3.h"
namespace SyntopiaCore {
namespace GLEngine {
using namespace SyntopiaCore::Math;
class Filter {
public:
Filter() {};
virtual float getWeight(float xSqr, float ySqr) = 0;
virtual int getExtent() = 0;
};
class BoxFilter : public Filter {
public:
BoxFilter() {};
virtual float getWeight(float, float) { return 1.0; }
virtual int getExtent() { return 0; };
};
class GaussianFilter : public Filter {
public:
GaussianFilter(double ext, double alpha) : extent(extent), alpha(alpha) {
this->extent = int(0.5+ext);
s = -exp(-alpha*(ext*ext));
};
virtual float getWeight(float xSqr, float ySqr) {
return (gaussian(xSqr)*gaussian(ySqr));
};
float gaussian(float v) {
float a= exp(-alpha*v)+s;
return a > 0 ? a : 0;
}
virtual int getExtent() { return extent; };
private:
int extent;
double s;
double alpha;
};
class TriangleFilter : public Filter {
public:
TriangleFilter(double halfwidth) : halfwidth(halfwidth) {
this->extent = int(halfwidth-0.5+1);
};
virtual float getWeight(float xSqr, float ySqr) {
return (triangle(sqrt(xSqr))*triangle(sqrt(ySqr)));
};
float triangle(float v) {
float a= 1-v/halfwidth;
return a > 0 ? a : 0;
}
virtual int getExtent() { return extent; };
private:
int extent;
double halfwidth;
};
// A simple sampler. Draws uniform numbers, but no stratification.
class Sampler {
public:
Sampler(Math::RandomNumberGenerator* rg);
virtual ~Sampler();
virtual Vector3f getAASample(int /*index*/) { return Vector3f(rg->getDouble(-0.5,0.5), rg->getDouble(-0.5,0.5),1.0); }
virtual Vector3f getAODirection(int /*index*/) { return rg->getUniform3D(); }
virtual Vector3f getLensSample(int /*index*/) { return rg->getUniform2D(); }
virtual void prepareSamples(int /*nSamplesSqrt*/, int /*nAOSamplesSqrt*/) {};
virtual Sampler* clone(Math::RandomNumberGenerator* rg) { return new Sampler(rg); }
protected:
Math::RandomNumberGenerator* rg;
};
// Stratified sampling
class StratifiedSampler : public Sampler {
public:
StratifiedSampler(Math::RandomNumberGenerator* rg) : Sampler(rg) {};
virtual Vector3f getAASample(int index);
virtual Vector3f getAODirection(int index);
virtual Vector3f getLensSample(int index);
Vector3f sampleSphere(double u1, double u2);
virtual void prepareSamples(int nSamplesSqrt, int nAOSamplesSqrt);
virtual Sampler* clone(Math::RandomNumberGenerator* rg) { return new StratifiedSampler(rg); }
private:
QVector<Vector3f> aoSamples;
QVector<Vector3f> aaSamples;
QVector<Vector3f> lensSamples;
};
// Stratified sampling
class ProgressiveStratifiedSampler : public Sampler {
public:
ProgressiveStratifiedSampler(Math::RandomNumberGenerator* rg) :
Sampler(rg) {}
virtual Vector3f getAASample(int index);
virtual Vector3f getAODirection(int index);
virtual Vector3f getLensSample(int index);
Vector3f sampleSphere(double u1, double u2);
virtual void prepareSamples(int nSamplesSqrt, int nAOSamplesSqrt);
virtual Sampler* clone(Math::RandomNumberGenerator* rg);
void setAAOrder(QVector<int> aaOrder) { this->aaOrder = aaOrder; }
private:
int aoSamplesSqrt;
int aaSamplesSqrt;
QVector<int> aaOrder;
};
}
}
|