Cycles: first step for implementation of non-progressive sampler that handles
[blender.git] / intern / cycles / render / light.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 "mesh.h"
23 #include "object.h"
24 #include "scene.h"
25 #include "shader.h"
26
27 #include "util_foreach.h"
28 #include "util_progress.h"
29
30 CCL_NAMESPACE_BEGIN
31
32 static void dump_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels)
33 {
34         /* create input */
35         int width = res;
36         int height = res;
37
38         device_vector<uint4> d_input;
39         device_vector<float4> d_output;
40
41         uint4 *d_input_data = d_input.resize(width*height);
42
43         for(int y = 0; y < height; y++) {
44                 for(int x = 0; x < width; x++) {
45                         float u = x/(float)width;
46                         float v = y/(float)height;
47
48                         uint4 in = make_uint4(__float_as_int(u), __float_as_int(v), 0, 0);
49                         d_input_data[x + y*width] = in;
50                 }
51         }
52
53         /* compute on device */
54         float4 *d_output_data = d_output.resize(width*height);
55         memset((void*)d_output.data_pointer, 0, d_output.memory_size());
56
57         device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
58
59         device->mem_alloc(d_input, MEM_READ_ONLY);
60         device->mem_copy_to(d_input);
61         device->mem_alloc(d_output, MEM_WRITE_ONLY);
62
63         DeviceTask main_task(DeviceTask::SHADER);
64         main_task.shader_input = d_input.device_pointer;
65         main_task.shader_output = d_output.device_pointer;
66         main_task.shader_eval_type = SHADER_EVAL_BACKGROUND;
67         main_task.shader_x = 0;
68         main_task.shader_w = width*height;
69
70         list<DeviceTask> split_tasks;
71         main_task.split_max_size(split_tasks, 128*128);
72
73         foreach(DeviceTask& task, split_tasks) {
74                 device->task_add(task);
75                 device->task_wait();
76         }
77
78         device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4));
79         device->mem_free(d_input);
80         device->mem_free(d_output);
81
82         d_output_data = reinterpret_cast<float4*>(d_output.data_pointer);
83
84         pixels.resize(width*height);
85
86         for(int y = 0; y < height; y++) {
87                 for(int x = 0; x < width; x++) {
88                         pixels[y*width + x].x = d_output_data[y*width + x].x;
89                         pixels[y*width + x].y = d_output_data[y*width + x].y;
90                         pixels[y*width + x].z = d_output_data[y*width + x].z;
91                 }
92         }
93 }
94
95 /* Light */
96
97 Light::Light()
98 {
99         type = LIGHT_POINT;
100
101         co = make_float3(0.0f, 0.0f, 0.0f);
102
103         dir = make_float3(0.0f, 0.0f, 0.0f);
104         size = 0.0f;
105
106         axisu = make_float3(0.0f, 0.0f, 0.0f);
107         sizeu = 1.0f;
108         axisv = make_float3(0.0f, 0.0f, 0.0f);
109         sizev = 1.0f;
110
111         map_resolution = 512;
112
113         spot_angle = M_PI_F/4.0f;
114         spot_smooth = 0.0f;
115
116         cast_shadow = true;
117         shader = 0;
118         samples = 1;
119 }
120
121 void Light::tag_update(Scene *scene)
122 {
123         scene->light_manager->need_update = true;
124 }
125
126 /* Light Manager */
127
128 LightManager::LightManager()
129 {
130         need_update = true;
131 }
132
133 LightManager::~LightManager()
134 {
135 }
136
137 void LightManager::device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
138 {
139         progress.set_status("Updating Lights", "Computing distribution");
140
141         /* count */
142         size_t num_lights = scene->lights.size();
143         size_t num_triangles = 0;
144
145         foreach(Object *object, scene->objects) {
146                 Mesh *mesh = object->mesh;
147                 bool have_emission = false;
148
149                 /* skip if we have no emission shaders */
150                 foreach(uint sindex, mesh->used_shaders) {
151                         Shader *shader = scene->shaders[sindex];
152
153                         if(shader->sample_as_light && shader->has_surface_emission) {
154                                 have_emission = true;
155                                 break;
156                         }
157                 }
158
159                 /* count triangles */
160                 if(have_emission) {
161                         for(size_t i = 0; i < mesh->triangles.size(); i++) {
162                                 Shader *shader = scene->shaders[mesh->shader[i]];
163
164                                 if(shader->sample_as_light && shader->has_surface_emission)
165                                         num_triangles++;
166                         }
167                 }
168         }
169
170         size_t num_distribution = num_triangles;
171         num_distribution += num_lights;
172
173         /* emission area */
174         float4 *distribution = dscene->light_distribution.resize(num_distribution + 1);
175         float totarea = 0.0f;
176
177         /* triangles */
178         size_t offset = 0;
179         int j = 0;
180
181         foreach(Object *object, scene->objects) {
182                 Mesh *mesh = object->mesh;
183                 bool have_emission = false;
184
185                 /* skip if we have no emission shaders */
186                 foreach(uint sindex, mesh->used_shaders) {
187                         Shader *shader = scene->shaders[sindex];
188
189                         if(shader->sample_as_light && shader->has_surface_emission) {
190                                 have_emission = true;
191                                 break;
192                         }
193                 }
194
195                 /* sum area */
196                 if(have_emission) {
197                         Transform tfm = object->tfm;
198                         int object_id = j;
199
200                         if(mesh->transform_applied)
201                                 object_id = ~object_id;
202
203                         for(size_t i = 0; i < mesh->triangles.size(); i++) {
204                                 Shader *shader = scene->shaders[mesh->shader[i]];
205
206                                 if(shader->sample_as_light && shader->has_surface_emission) {
207                                         distribution[offset].x = totarea;
208                                         distribution[offset].y = __int_as_float(i + mesh->tri_offset);
209                                         distribution[offset].z = 1.0f;
210                                         distribution[offset].w = __int_as_float(object_id);
211                                         offset++;
212
213                                         Mesh::Triangle t = mesh->triangles[i];
214                                         float3 p1 = transform_point(&tfm, mesh->verts[t.v[0]]);
215                                         float3 p2 = transform_point(&tfm, mesh->verts[t.v[1]]);
216                                         float3 p3 = transform_point(&tfm, mesh->verts[t.v[2]]);
217
218                                         totarea += triangle_area(p1, p2, p3);
219                                 }
220                         }
221                 }
222
223                 if(progress.get_cancel()) return;
224
225                 j++;
226         }
227
228         float trianglearea = totarea;
229
230         /* point lights */
231         float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f;
232
233         for(int i = 0; i < scene->lights.size(); i++, offset++) {
234                 distribution[offset].x = totarea;
235                 distribution[offset].y = __int_as_float(~(int)i);
236                 distribution[offset].z = 1.0f;
237                 distribution[offset].w = scene->lights[i]->size;
238                 totarea += lightarea;
239         }
240
241         /* normalize cumulative distribution functions */
242         distribution[num_distribution].x = totarea;
243         distribution[num_distribution].y = 0.0f;
244         distribution[num_distribution].z = 0.0f;
245         distribution[num_distribution].w = 0.0f;
246
247         if(totarea > 0.0f) {
248                 for(size_t i = 0; i < num_distribution; i++)
249                         distribution[i].x /= totarea;
250                 distribution[num_distribution].x = 1.0f;
251         }
252
253         if(progress.get_cancel()) return;
254
255         /* update device */
256         KernelIntegrator *kintegrator = &dscene->data.integrator;
257         kintegrator->use_direct_light = (totarea > 0.0f);
258
259         if(kintegrator->use_direct_light) {
260                 /* number of emissives */
261                 kintegrator->num_distribution = (totarea > 0.0f)? num_distribution: 0;
262
263                 /* precompute pdfs */
264                 kintegrator->pdf_triangles = 0.0f;
265                 kintegrator->pdf_lights = 0.0f;
266
267                 /* sample one, with 0.5 probability of light or triangle */
268                 kintegrator->num_all_lights = num_lights;
269
270                 if(trianglearea > 0.0f) {
271                         kintegrator->pdf_triangles = 1.0f/trianglearea;
272                         if(num_lights)
273                                 kintegrator->pdf_triangles *= 0.5f;
274                 }
275
276                 if(num_lights) {
277                         kintegrator->pdf_lights = 1.0f/num_lights;
278                         if(trianglearea > 0.0f)
279                                 kintegrator->pdf_lights *= 0.5f;
280                 }
281
282                 /* CDF */
283                 device->tex_alloc("__light_distribution", dscene->light_distribution);
284         }
285         else
286                 dscene->light_distribution.clear();
287 }
288
289 void LightManager::device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
290 {
291         KernelIntegrator *kintegrator = &dscene->data.integrator;
292         Light *background_light = NULL;
293
294         /* find background light */
295         foreach(Light *light, scene->lights) {
296                 if(light->type == LIGHT_BACKGROUND) {
297                         background_light = light;
298                         break;
299                 }
300         }
301
302         /* no background light found, signal renderer to skip sampling */
303         if(!background_light) {
304                 kintegrator->pdf_background_res = 0;
305                 return;
306         }
307
308         progress.set_status("Updating Lights", "Importance map");
309
310         assert(kintegrator->use_direct_light);
311
312         /* get the resolution from the light's size (we stuff it in there) */
313         int res = background_light->map_resolution;
314         kintegrator->pdf_background_res = res;
315
316         assert(res > 0);
317
318         vector<float3> pixels;
319         dump_background_pixels(device, dscene, res, pixels);
320
321         if(progress.get_cancel())
322                 return;
323
324         /* build row distributions and column distribution for the infinite area environment light */
325         int cdf_count = res + 1;
326         float2 *marg_cdf = dscene->light_background_marginal_cdf.resize(cdf_count);
327         float2 *cond_cdf = dscene->light_background_conditional_cdf.resize(cdf_count * cdf_count);
328
329         /* conditional CDFs (rows, U direction) */
330         for(int i = 0; i < res; i++) {
331                 float sin_theta = sinf(M_PI_F * (i + 0.5f) / res);
332                 float3 env_color = pixels[i * res];
333                 float ave_luminamce = average(env_color);
334
335                 cond_cdf[i * cdf_count].x = ave_luminamce * sin_theta;
336                 cond_cdf[i * cdf_count].y = 0.0f;
337
338                 for(int j = 1; j < res; j++) {
339                         env_color = pixels[i * res + j];
340                         ave_luminamce = average(env_color);
341
342                         cond_cdf[i * cdf_count + j].x = ave_luminamce * sin_theta;
343                         cond_cdf[i * cdf_count + j].y = cond_cdf[i * cdf_count + j - 1].y + cond_cdf[i * cdf_count + j - 1].x / res;
344                 }
345
346                 float cdf_total = cond_cdf[i * cdf_count + res - 1].y + cond_cdf[i * cdf_count + res - 1].x / res;
347
348                 /* stuff the total into the brightness value for the last entry, because
349                  * we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
350                 cond_cdf[i * cdf_count + res].x = cdf_total;
351
352                 if(cdf_total > 0.0f)
353                         for(int j = 1; j < res; j++)
354                                 cond_cdf[i * cdf_count + j].y /= cdf_total;
355
356                 cond_cdf[i * cdf_count + res].y = 1.0f;
357         }
358
359         /* marginal CDFs (column, V direction, sum of rows) */
360         marg_cdf[0].x = cond_cdf[res].x;
361         marg_cdf[0].y = 0.0f;
362
363         for(int i = 1; i < res; i++) {
364                 marg_cdf[i].x = cond_cdf[i * cdf_count + res].x;
365                 marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res;
366         }
367
368         float cdf_total = marg_cdf[res - 1].y + marg_cdf[res - 1].x / res;
369         marg_cdf[res].x = cdf_total;
370
371         if(cdf_total > 0.0f)
372                 for(int i = 1; i < res; i++)
373                         marg_cdf[i].y /= cdf_total;
374
375         marg_cdf[res].y = 1.0f;
376
377         /* update device */
378         device->tex_alloc("__light_background_marginal_cdf", dscene->light_background_marginal_cdf);
379         device->tex_alloc("__light_background_conditional_cdf", dscene->light_background_conditional_cdf);
380 }
381
382 void LightManager::device_update_points(Device *device, DeviceScene *dscene, Scene *scene)
383 {
384         if(scene->lights.size() == 0)
385                 return;
386
387         float4 *light_data = dscene->light_data.resize(scene->lights.size()*LIGHT_SIZE);
388
389         if(!device->info.advanced_shading) {
390                 /* remove unsupported light */
391                 foreach(Light *light, scene->lights) {
392                         if(light->type == LIGHT_BACKGROUND) {
393                                 scene->lights.erase(std::remove(scene->lights.begin(), scene->lights.end(), light), scene->lights.end());
394                                 break;
395                         }
396                 }
397         }
398
399         for(size_t i = 0; i < scene->lights.size(); i++) {
400                 Light *light = scene->lights[i];
401                 float3 co = light->co;
402                 float3 dir = normalize(light->dir);
403                 int shader_id = scene->shader_manager->get_shader_id(scene->lights[i]->shader);
404                 float samples = __int_as_float(light->samples);
405
406                 if(!light->cast_shadow)
407                         shader_id &= ~SHADER_CAST_SHADOW;
408
409                 if(light->type == LIGHT_POINT) {
410                         shader_id &= ~SHADER_AREA_LIGHT;
411
412                         light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
413                         light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
414                         light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
415                         light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
416                 }
417                 else if(light->type == LIGHT_DISTANT) {
418                         shader_id &= ~SHADER_AREA_LIGHT;
419
420                         light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), dir.x, dir.y, dir.z);
421                         light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
422                         light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
423                         light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
424                 }
425                 else if(light->type == LIGHT_BACKGROUND) {
426                         shader_id &= ~SHADER_AREA_LIGHT;
427
428                         light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), 0.0f, 0.0f, 0.0f);
429                         light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f);
430                         light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
431                         light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
432                 }
433                 else if(light->type == LIGHT_AREA) {
434                         float3 axisu = light->axisu*(light->sizeu*light->size);
435                         float3 axisv = light->axisv*(light->sizev*light->size);
436
437                         light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
438                         light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z);
439                         light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z);
440                         light_data[i*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z);
441                 }
442                 else if(light->type == LIGHT_SPOT) {
443                         shader_id &= ~SHADER_AREA_LIGHT;
444
445                         float spot_angle = cosf(light->spot_angle*0.5f);
446                         float spot_smooth = (1.0f - spot_angle)*light->spot_smooth;
447
448                         light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
449                         light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y);
450                         light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f);
451                         light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
452                 }
453         }
454         
455         device->tex_alloc("__light_data", dscene->light_data);
456 }
457
458 void LightManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
459 {
460         if(!need_update)
461                 return;
462
463         device_free(device, dscene);
464
465         device_update_points(device, dscene, scene);
466         if(progress.get_cancel()) return;
467
468         device_update_distribution(device, dscene, scene, progress);
469         if(progress.get_cancel()) return;
470
471         device_update_background(device, dscene, scene, progress);
472         if(progress.get_cancel()) return;
473
474         need_update = false;
475 }
476
477 void LightManager::device_free(Device *device, DeviceScene *dscene)
478 {
479         device->tex_free(dscene->light_distribution);
480         device->tex_free(dscene->light_data);
481         device->tex_free(dscene->light_background_marginal_cdf);
482         device->tex_free(dscene->light_background_conditional_cdf);
483
484         dscene->light_distribution.clear();
485         dscene->light_data.clear();
486         dscene->light_background_marginal_cdf.clear();
487         dscene->light_background_conditional_cdf.clear();
488 }
489
490 void LightManager::tag_update(Scene *scene)
491 {
492         need_update = true;
493 }
494
495 CCL_NAMESPACE_END
496