00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _FILTER_H
00023 #define _FILTER_H
00024
00025 namespace luxrays {
00026
00027
00028
00029
00030
00031 class Filter {
00032 public:
00033
00034 Filter(const float xw, const float yw) : xWidth(xw), yWidth(yw),
00035 invXWidth(1.f / xw), invYWidth(1.f / yw) { }
00036 virtual ~Filter() { }
00037
00038 virtual float Evaluate(const float x, const float y) const = 0;
00039
00040
00041 const float xWidth, yWidth;
00042 const float invXWidth, invYWidth;
00043 };
00044
00045 class GaussianFilter : public Filter {
00046 public:
00047
00048 GaussianFilter(const float xw = 2.f, const float yw = 2.f, const float a = 2.f) :
00049 Filter(xw, yw) {
00050 alpha = a;
00051 expX = expf(-alpha * xWidth * xWidth);
00052 expY = expf(-alpha * yWidth * yWidth);
00053 }
00054
00055 virtual ~GaussianFilter() { }
00056
00057 float Evaluate(const float x, const float y) const {
00058 return Gaussian(x, expX) * Gaussian(y, expY);
00059 }
00060
00061 private:
00062
00063 float alpha;
00064 float expX, expY;
00065
00066
00067 float Gaussian(float d, float expv) const {
00068 return Max(0.f, expf(-alpha * d * d) - expv);
00069 }
00070 };
00071
00072
00073
00074
00075
00076 class FilterLUT {
00077 public:
00078 FilterLUT(const Filter &filter, const float offsetX, const float offsetY) {
00079 const int x0 = Ceil2Int(offsetX - filter.xWidth);
00080 const int x1 = Floor2Int(offsetX + filter.xWidth);
00081 const int y0 = Ceil2Int(offsetY - filter.yWidth);
00082 const int y1 = Floor2Int(offsetY + filter.yWidth);
00083 lutWidth = x1 - x0 + 1;
00084 lutHeight = y1 - y0 + 1;
00085 lut = new float[lutWidth * lutHeight];
00086
00087 float filterNorm = 0.f;
00088 unsigned int index = 0;
00089 for (int iy = y0; iy <= y1; ++iy) {
00090 for (int ix = x0; ix <= x1; ++ix) {
00091 const float filterVal = filter.Evaluate(fabsf(ix - offsetX), fabsf(iy - offsetY));
00092 filterNorm += filterVal;
00093 lut[index++] = filterVal;
00094 }
00095 }
00096
00097
00098 filterNorm = 1.f / filterNorm;
00099 index = 0;
00100 for (int iy = y0; iy <= y1; ++iy) {
00101 for (int ix = x0; ix <= x1; ++ix)
00102 lut[index++] *= filterNorm;
00103 }
00104 }
00105
00106 ~FilterLUT() {
00107 delete[] lut;
00108 }
00109
00110 const unsigned int GetWidth() const { return lutWidth; }
00111 const unsigned int GetHeight() const { return lutHeight; }
00112
00113 const float *GetLUT() const {
00114 return lut;
00115 }
00116
00117 friend std::ostream &operator<<(std::ostream &os, const FilterLUT &f);
00118
00119 private:
00120 unsigned int lutWidth, lutHeight;
00121 float *lut;
00122 };
00123
00124 inline std::ostream &operator<<(std::ostream &os, const FilterLUT &f) {
00125 os << "FilterLUT[(" << f.lutWidth << "x" << f.lutHeight << "),";
00126
00127 os << "[";
00128 for (unsigned int iy = 0; iy < f.lutHeight; ++iy) {
00129 os << "[";
00130 for (unsigned int ix = 0; ix < f.lutWidth; ++ix) {
00131 os << f.lut[ix + iy * f.lutWidth];
00132 if (ix != f.lutWidth - 1)
00133 os << ",";
00134 }
00135 os << "]";
00136 }
00137 os << "]";
00138
00139 return os;
00140 }
00141
00142 class FilterLUTs {
00143 public:
00144 FilterLUTs(const Filter &filter, const unsigned int size) {
00145 lutsSize = size + 1;
00146 step = 1.f / float(size);
00147
00148 luts = new FilterLUT*[lutsSize * lutsSize];
00149
00150 for (unsigned int iy = 0; iy < lutsSize; ++iy) {
00151 for (unsigned int ix = 0; ix < lutsSize; ++ix) {
00152 const float x = ix * step - 0.5f + step / 2.f;
00153 const float y = iy * step - 0.5f + step / 2.f;
00154
00155 luts[ix + iy * lutsSize] = new FilterLUT(filter, x, y);
00156
00157
00158
00159
00160
00161 }
00162 }
00163 }
00164
00165 ~FilterLUTs() {
00166 for (unsigned int iy = 0; iy < lutsSize; ++iy)
00167 for (unsigned int ix = 0; ix < lutsSize; ++ix)
00168 delete luts[ix + iy * lutsSize];
00169
00170 delete[] luts;
00171 }
00172
00173 const FilterLUT *GetLUT(const float x, const float y) const {
00174 const int ix = Max<unsigned int>(0, Min<unsigned int>(Floor2Int(lutsSize * (x + 0.5f)), lutsSize - 1));
00175 const int iy = Max<unsigned int>(0, Min<unsigned int>(Floor2Int(lutsSize * (y + 0.5f)), lutsSize - 1));
00176
00177 return luts[ix + iy * lutsSize];
00178 }
00179
00180 private:
00181 unsigned int lutsSize;
00182 float step;
00183 FilterLUT **luts;
00184 };
00185
00186 }
00187
00188 #endif