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 "kernel_types.h"
26
#include "util_algorithm.h"
27
#include "util_debug.h"
28
#include "util_math.h"
34
filter_type = FILTER_BOX;
43
static float filter_func_box(float v, float width)
48
static float filter_func_gaussian(float v, float width)
51
return (float)expf((float)-2*v*v);
54
static vector<float> filter_table(FilterType type, float width)
56
const int filter_table_size = FILTER_TABLE_SIZE-1;
57
vector<float> filter_table_cdf(filter_table_size+1);
58
vector<float> filter_table(filter_table_size+1);
59
float (*filter_func)(float, float) = NULL;
60
int i, half_size = filter_table_size/2;
64
filter_func = filter_func_box;
67
filter_func = filter_func_gaussian;
73
/* compute cumulative distribution function */
74
filter_table_cdf[0] = 0.0f;
76
for(i = 0; i < filter_table_size; i++) {
77
float x = i*width*0.5f/(filter_table_size-1);
78
float y = filter_func(x, width);
79
filter_table_cdf[i+1] += filter_table_cdf[i] + fabsf(y);
82
for(i = 0; i <= filter_table_size; i++)
83
filter_table_cdf[i] /= filter_table_cdf[filter_table_size];
85
/* create importance sampling table */
86
for(i = 0; i <= half_size; i++) {
87
float x = i/(float)half_size;
88
int index = upper_bound(filter_table_cdf.begin(), filter_table_cdf.end(), x) - filter_table_cdf.begin();
91
if(index < filter_table_size+1) {
92
t = (x - filter_table_cdf[index])/(filter_table_cdf[index+1] - filter_table_cdf[index]);
96
index = filter_table_size;
99
float y = ((index + t)/(filter_table_size))*width;
101
filter_table[half_size+i] = 0.5f*(1.0f + y);
102
filter_table[half_size-i] = 0.5f*(1.0f - y);
108
void Filter::device_update(Device *device, DeviceScene *dscene)
113
device_free(device, dscene);
115
/* update __filter_table */
116
vector<float> table = filter_table(filter_type, filter_width);
118
dscene->filter_table.copy(&table[0], table.size());
119
device->tex_alloc("__filter_table", dscene->filter_table, true);
124
void Filter::device_free(Device *device, DeviceScene *dscene)
126
device->tex_free(dscene->filter_table);
127
dscene->filter_table.clear();
130
bool Filter::modified(const Filter& filter)
132
return !(filter_type == filter.filter_type &&
133
filter_width == filter.filter_width);
136
void Filter::tag_update(Scene *scene)