Cycles: first step for implementation of non-progressive sampler that handles
[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         progressive = true;
58
59         need_update = true;
60 }
61
62 Integrator::~Integrator()
63 {
64 }
65
66 void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene)
67 {
68         if(!need_update)
69                 return;
70
71         device_free(device, dscene);
72
73         KernelIntegrator *kintegrator = &dscene->data.integrator;
74
75         /* integrator parameters */
76         kintegrator->max_bounce = max_bounce + 1;
77         if(probalistic_termination)
78                 kintegrator->min_bounce = min_bounce + 1;
79         else
80                 kintegrator->min_bounce = kintegrator->max_bounce;
81
82         kintegrator->max_diffuse_bounce = max_diffuse_bounce + 1;
83         kintegrator->max_glossy_bounce = max_glossy_bounce + 1;
84         kintegrator->max_transmission_bounce = max_transmission_bounce + 1;
85
86         kintegrator->transparent_max_bounce = transparent_max_bounce + 1;
87         if(transparent_probalistic)
88                 kintegrator->transparent_min_bounce = transparent_min_bounce + 1;
89         else
90                 kintegrator->transparent_min_bounce = kintegrator->transparent_max_bounce;
91
92         kintegrator->transparent_shadows = transparent_shadows;
93
94         kintegrator->no_caustics = no_caustics;
95         kintegrator->filter_glossy = (filter_glossy == 0.0f)? FLT_MAX: 1.0f/filter_glossy;
96
97         kintegrator->seed = hash_int(seed);
98         kintegrator->layer_flag = layer_flag << PATH_RAY_LAYER_SHIFT;
99
100         kintegrator->use_ambient_occlusion =
101                 ((dscene->data.film.pass_flag & PASS_AO) || dscene->data.background.ao_factor != 0.0f);
102         
103         kintegrator->sample_clamp = (sample_clamp == 0.0f)? FLT_MAX: sample_clamp*3.0f;
104
105         kintegrator->progressive = progressive;
106         kintegrator->diffuse_samples = diffuse_samples;
107         kintegrator->glossy_samples = glossy_samples;
108         kintegrator->transmission_samples = transmission_samples;
109         kintegrator->ao_samples = ao_samples;
110         kintegrator->mesh_light_samples = mesh_light_samples;
111
112         /* sobol directions table */
113         int max_samples = 1;
114
115         if(!progressive) {
116                 foreach(Light *light, scene->lights)
117                         max_samples = max(max_samples, light->samples);
118
119                 max_samples = max(max_samples, max(diffuse_samples, max(glossy_samples, transmission_samples)));
120                 max_samples = max(max_samples, max(ao_samples, mesh_light_samples));
121         }
122
123         max_samples *= (max_bounce + transparent_max_bounce + 2);
124
125         int dimensions = PRNG_BASE_NUM + max_samples*PRNG_BOUNCE_NUM;
126         uint *directions = dscene->sobol_directions.resize(SOBOL_BITS*dimensions);
127
128         sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
129
130         device->tex_alloc("__sobol_directions", dscene->sobol_directions);
131
132         need_update = false;
133 }
134
135 void Integrator::device_free(Device *device, DeviceScene *dscene)
136 {
137         device->tex_free(dscene->sobol_directions);
138         dscene->sobol_directions.clear();
139 }
140
141 bool Integrator::modified(const Integrator& integrator)
142 {
143         return !(min_bounce == integrator.min_bounce &&
144                 max_bounce == integrator.max_bounce &&
145                 max_diffuse_bounce == integrator.max_diffuse_bounce &&
146                 max_glossy_bounce == integrator.max_glossy_bounce &&
147                 max_transmission_bounce == integrator.max_transmission_bounce &&
148                 probalistic_termination == integrator.probalistic_termination &&
149                 transparent_min_bounce == integrator.transparent_min_bounce &&
150                 transparent_max_bounce == integrator.transparent_max_bounce &&
151                 transparent_probalistic == integrator.transparent_probalistic &&
152                 transparent_shadows == integrator.transparent_shadows &&
153                 no_caustics == integrator.no_caustics &&
154                 filter_glossy == integrator.filter_glossy &&
155                 layer_flag == integrator.layer_flag &&
156                 seed == integrator.seed &&
157                 sample_clamp == integrator.sample_clamp &&
158                 progressive == integrator.progressive &&
159                 diffuse_samples == integrator.diffuse_samples &&
160                 glossy_samples == integrator.glossy_samples &&
161                 transmission_samples == integrator.transmission_samples &&
162                 ao_samples == integrator.ao_samples &&
163                 mesh_light_samples == integrator.mesh_light_samples &&
164                 motion_blur == integrator.motion_blur);
165 }
166
167 void Integrator::tag_update(Scene *scene)
168 {
169         need_update = true;
170 }
171
172 CCL_NAMESPACE_END
173