731ffd9e271f6031280d2fc15ac021f72d20aa7a
[blender.git] / intern / cycles / render / integrator.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #include "device.h"
20 #include "integrator.h"
21 #include "light.h"
22 #include "scene.h"
23 #include "sobol.h"
24
25 #include "util_foreach.h"
26 #include "util_hash.h"
27
28 CCL_NAMESPACE_BEGIN
29
30 Integrator::Integrator()
31 {
32         min_bounce = 2;
33         max_bounce = 7;
34
35         max_diffuse_bounce = max_bounce;
36         max_glossy_bounce = max_bounce;
37         max_transmission_bounce = max_bounce;
38         probalistic_termination = true;
39
40         transparent_min_bounce = min_bounce;
41         transparent_max_bounce = max_bounce;
42         transparent_probalistic = true;
43         transparent_shadows = false;
44
45         no_caustics = false;
46         filter_glossy = 0.0f;
47         seed = 0;
48         layer_flag = ~0;
49         sample_clamp = 0.0f;
50         motion_blur = false;
51
52         diffuse_samples = 1;
53         glossy_samples = 1;
54         transmission_samples = 1;
55         ao_samples = 1;
56         mesh_light_samples = 1;
57         subsurface_samples = 1;
58         progressive = true;
59
60         need_update = true;
61 }
62
63 Integrator::~Integrator()
64 {
65 }
66
67 void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene)
68 {
69         if(!need_update)
70                 return;
71
72         device_free(device, dscene);
73
74         KernelIntegrator *kintegrator = &dscene->data.integrator;
75
76         /* integrator parameters */
77         kintegrator->max_bounce = max_bounce + 1;
78         if(probalistic_termination)
79                 kintegrator->min_bounce = min_bounce + 1;
80         else
81                 kintegrator->min_bounce = kintegrator->max_bounce;
82
83         kintegrator->max_diffuse_bounce = max_diffuse_bounce + 1;
84         kintegrator->max_glossy_bounce = max_glossy_bounce + 1;
85         kintegrator->max_transmission_bounce = max_transmission_bounce + 1;
86
87         kintegrator->transparent_max_bounce = transparent_max_bounce + 1;
88         if(transparent_probalistic)
89                 kintegrator->transparent_min_bounce = transparent_min_bounce + 1;
90         else
91                 kintegrator->transparent_min_bounce = kintegrator->transparent_max_bounce;
92
93         kintegrator->transparent_shadows = transparent_shadows;
94
95         kintegrator->no_caustics = no_caustics;
96         kintegrator->filter_glossy = (filter_glossy == 0.0f)? FLT_MAX: 1.0f/filter_glossy;
97
98         kintegrator->seed = hash_int(seed);
99         kintegrator->layer_flag = layer_flag << PATH_RAY_LAYER_SHIFT;
100
101         kintegrator->use_ambient_occlusion =
102                 ((dscene->data.film.pass_flag & PASS_AO) || dscene->data.background.ao_factor != 0.0f);
103         
104         kintegrator->sample_clamp = (sample_clamp == 0.0f)? FLT_MAX: sample_clamp*3.0f;
105
106         kintegrator->progressive = progressive;
107         kintegrator->diffuse_samples = diffuse_samples;
108         kintegrator->glossy_samples = glossy_samples;
109         kintegrator->transmission_samples = transmission_samples;
110         kintegrator->ao_samples = ao_samples;
111         kintegrator->mesh_light_samples = mesh_light_samples;
112         kintegrator->subsurface_samples = subsurface_samples;
113
114         /* sobol directions table */
115         int max_samples = 1;
116
117         if(!progressive) {
118                 foreach(Light *light, scene->lights)
119                         max_samples = max(max_samples, light->samples);
120
121                 max_samples = max(max_samples, max(diffuse_samples, max(glossy_samples, transmission_samples)));
122                 max_samples = max(max_samples, max(ao_samples, max(mesh_light_samples, subsurface_samples)));
123         }
124
125         max_samples *= (max_bounce + transparent_max_bounce + 2);
126
127         int dimensions = PRNG_BASE_NUM + max_samples*PRNG_BOUNCE_NUM;
128         dimensions = min(dimensions, SOBOL_MAX_DIMENSIONS);
129
130         uint *directions = dscene->sobol_directions.resize(SOBOL_BITS*dimensions);
131
132         sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
133
134         device->tex_alloc("__sobol_directions", dscene->sobol_directions);
135
136         need_update = false;
137 }
138
139 void Integrator::device_free(Device *device, DeviceScene *dscene)
140 {
141         device->tex_free(dscene->sobol_directions);
142         dscene->sobol_directions.clear();
143 }
144
145 bool Integrator::modified(const Integrator& integrator)
146 {
147         return !(min_bounce == integrator.min_bounce &&
148                 max_bounce == integrator.max_bounce &&
149                 max_diffuse_bounce == integrator.max_diffuse_bounce &&
150                 max_glossy_bounce == integrator.max_glossy_bounce &&
151                 max_transmission_bounce == integrator.max_transmission_bounce &&
152                 probalistic_termination == integrator.probalistic_termination &&
153                 transparent_min_bounce == integrator.transparent_min_bounce &&
154                 transparent_max_bounce == integrator.transparent_max_bounce &&
155                 transparent_probalistic == integrator.transparent_probalistic &&
156                 transparent_shadows == integrator.transparent_shadows &&
157                 no_caustics == integrator.no_caustics &&
158                 filter_glossy == integrator.filter_glossy &&
159                 layer_flag == integrator.layer_flag &&
160                 seed == integrator.seed &&
161                 sample_clamp == integrator.sample_clamp &&
162                 progressive == integrator.progressive &&
163                 diffuse_samples == integrator.diffuse_samples &&
164                 glossy_samples == integrator.glossy_samples &&
165                 transmission_samples == integrator.transmission_samples &&
166                 ao_samples == integrator.ao_samples &&
167                 mesh_light_samples == integrator.mesh_light_samples &&
168                 subsurface_samples == integrator.subsurface_samples &&
169                 motion_blur == integrator.motion_blur);
170 }
171
172 void Integrator::tag_update(Scene *scene)
173 {
174         need_update = true;
175 }
176
177 CCL_NAMESPACE_END
178