2 * Copyright 2011, Blender Foundation.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include "util_algorithm.h"
25 #include "util_debug.h"
26 #include "util_math.h"
32 filter_type = FILTER_BOX;
41 static float filter_func_box(float v, float width)
46 static float filter_func_gaussian(float v, float width)
49 return (float)expf((float)-2*v*v);
52 static vector<float> filter_table(FilterType type, float width)
54 const int filter_table_size = 256;
55 vector<float> filter_table_cdf(filter_table_size+1);
56 vector<float> filter_table(filter_table_size+1);
57 float (*filter_func)(float, float) = NULL;
58 int i, half_size = filter_table_size/2;
62 filter_func = filter_func_box;
65 filter_func = filter_func_gaussian;
71 /* compute cumulative distribution function */
72 filter_table_cdf[0] = 0.0f;
74 for(i=0; i<filter_table_size; i++) {
75 float x = i*width*0.5f/(filter_table_size-1);
76 float y = filter_func(x, width);
77 filter_table_cdf[i+1] += filter_table_cdf[i] + fabsf(y);
80 for(i=0; i<=filter_table_size; i++)
81 filter_table_cdf[i] /= filter_table_cdf[filter_table_size];
83 /* create importance sampling table */
84 for(i=0; i<=half_size; i++) {
85 float x = i/(float)half_size;
86 int index = upper_bound(filter_table_cdf.begin(), filter_table_cdf.end(), x) - filter_table_cdf.begin();
89 if(index < filter_table_size+1) {
90 t = (x - filter_table_cdf[index])/(filter_table_cdf[index+1] - filter_table_cdf[index]);
94 index = filter_table_size;
97 float y = ((index + t)/(filter_table_size))*width;
99 filter_table[half_size+i] = 0.5f*(1.0f + y);
100 filter_table[half_size-i] = 0.5f*(1.0f - y);
106 void Filter::device_update(Device *device, DeviceScene *dscene)
111 device_free(device, dscene);
113 /* update __filter_table */
114 vector<float> table = filter_table(filter_type, filter_width);
116 dscene->filter_table.copy(&table[0], table.size());
117 device->tex_alloc("__filter_table", dscene->filter_table, true);
122 void Filter::device_free(Device *device, DeviceScene *dscene)
124 device->tex_free(dscene->filter_table);
125 dscene->filter_table.clear();
128 bool Filter::modified(const Filter& filter)
130 return !(filter_type == filter.filter_type &&
131 filter_width == filter.filter_width);
134 void Filter::tag_update(Scene *scene)