Cycles: Make all #include statements relative to cycles source directory
[blender.git] / intern / cycles / render / light.cpp
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "render/background.h"
18 #include "device/device.h"
19 #include "render/integrator.h"
20 #include "render/film.h"
21 #include "render/light.h"
22 #include "render/mesh.h"
23 #include "render/object.h"
24 #include "render/scene.h"
25 #include "render/shader.h"
26
27 #include "util/util_foreach.h"
28 #include "util/util_progress.h"
29 #include "util/util_logging.h"
30
31 CCL_NAMESPACE_BEGIN
32
33 static void shade_background_pixels(Device *device, DeviceScene *dscene, int res, vector<float3>& pixels, Progress& progress)
34 {
35         /* create input */
36         int width = res;
37         int height = res;
38
39         device_vector<uint4> d_input;
40         device_vector<float4> d_output;
41
42         uint4 *d_input_data = d_input.resize(width*height);
43
44         for(int y = 0; y < height; y++) {
45                 for(int x = 0; x < width; x++) {
46                         float u = (x + 0.5f)/width;
47                         float v = (y + 0.5f)/height;
48
49                         uint4 in = make_uint4(__float_as_int(u), __float_as_int(v), 0, 0);
50                         d_input_data[x + y*width] = in;
51                 }
52         }
53
54         /* compute on device */
55         d_output.resize(width*height);
56         memset((void*)d_output.data_pointer, 0, d_output.memory_size());
57
58         device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
59
60         device->mem_alloc("shade_background_pixels_input", d_input, MEM_READ_ONLY);
61         device->mem_copy_to(d_input);
62         device->mem_alloc("shade_background_pixels_output", d_output, MEM_WRITE_ONLY);
63
64         DeviceTask main_task(DeviceTask::SHADER);
65         main_task.shader_input = d_input.device_pointer;
66         main_task.shader_output = d_output.device_pointer;
67         main_task.shader_eval_type = SHADER_EVAL_BACKGROUND;
68         main_task.shader_x = 0;
69         main_task.shader_w = width*height;
70         main_task.num_samples = 1;
71         main_task.get_cancel = function_bind(&Progress::get_cancel, &progress);
72
73         /* disabled splitting for now, there's an issue with multi-GPU mem_copy_from */
74         list<DeviceTask> split_tasks;
75         main_task.split(split_tasks, 1, 128*128);
76
77         foreach(DeviceTask& task, split_tasks) {
78                 device->task_add(task);
79                 device->task_wait();
80                 device->mem_copy_from(d_output, task.shader_x, 1, task.shader_w, sizeof(float4));
81         }
82
83         device->mem_free(d_input);
84         device->mem_free(d_output);
85
86         d_input.clear();
87
88         float4 *d_output_data = reinterpret_cast<float4*>(d_output.data_pointer);
89
90         pixels.resize(width*height);
91
92         for(int y = 0; y < height; y++) {
93                 for(int x = 0; x < width; x++) {
94                         pixels[y*width + x].x = d_output_data[y*width + x].x;
95                         pixels[y*width + x].y = d_output_data[y*width + x].y;
96                         pixels[y*width + x].z = d_output_data[y*width + x].z;
97                 }
98         }
99 }
100
101 /* Light */
102
103 NODE_DEFINE(Light)
104 {
105         NodeType* type = NodeType::add("light", create);
106
107         static NodeEnum type_enum;
108         type_enum.insert("point", LIGHT_POINT);
109         type_enum.insert("distant", LIGHT_DISTANT);
110         type_enum.insert("background", LIGHT_BACKGROUND);
111         type_enum.insert("area", LIGHT_AREA);
112         type_enum.insert("spot", LIGHT_SPOT);
113         SOCKET_ENUM(type, "Type", type_enum, LIGHT_POINT);
114
115         SOCKET_POINT(co, "Co", make_float3(0.0f, 0.0f, 0.0f));
116
117         SOCKET_VECTOR(dir, "Dir", make_float3(0.0f, 0.0f, 0.0f));
118         SOCKET_FLOAT(size, "Size", 0.0f);
119
120         SOCKET_VECTOR(axisu, "Axis U", make_float3(0.0f, 0.0f, 0.0f));
121         SOCKET_FLOAT(sizeu, "Size U", 1.0f);
122         SOCKET_VECTOR(axisv, "Axis V", make_float3(0.0f, 0.0f, 0.0f));
123         SOCKET_FLOAT(sizev, "Size V", 1.0f);
124
125         SOCKET_INT(map_resolution, "Map Resolution", 512);
126
127         SOCKET_FLOAT(spot_angle, "Spot Angle", M_PI_4_F);
128         SOCKET_FLOAT(spot_smooth, "Spot Smooth", 0.0f);
129
130         SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
131
132         SOCKET_BOOLEAN(cast_shadow, "Cast Shadow", true);
133         SOCKET_BOOLEAN(use_mis, "Use Mis", false);
134         SOCKET_BOOLEAN(use_diffuse, "Use Diffuse", true);
135         SOCKET_BOOLEAN(use_glossy, "Use Glossy", true);
136         SOCKET_BOOLEAN(use_transmission, "Use Transmission", true);
137         SOCKET_BOOLEAN(use_scatter, "Use Scatter", true);
138
139         SOCKET_INT(samples, "Samples", 1);
140         SOCKET_INT(max_bounces, "Max Bounces", 1024);
141
142         SOCKET_BOOLEAN(is_portal, "Is Portal", false);
143         SOCKET_BOOLEAN(is_enabled, "Is Enabled", true);
144
145         SOCKET_NODE(shader, "Shader", &Shader::node_type);
146
147         return type;
148 }
149
150 Light::Light()
151 : Node(node_type)
152 {
153 }
154
155 void Light::tag_update(Scene *scene)
156 {
157         scene->light_manager->need_update = true;
158 }
159
160 bool Light::has_contribution(Scene *scene)
161 {
162         if(is_portal) {
163                 return false;
164         }
165         if(type == LIGHT_BACKGROUND) {
166                 return true;
167         }
168         return (shader) ? shader->has_surface_emission : scene->default_light->has_surface_emission;
169 }
170
171 /* Light Manager */
172
173 LightManager::LightManager()
174 {
175         need_update = true;
176         use_light_visibility = false;
177 }
178
179 LightManager::~LightManager()
180 {
181 }
182
183 bool LightManager::has_background_light(Scene *scene)
184 {
185         foreach(Light *light, scene->lights) {
186                 if(light->type == LIGHT_BACKGROUND) {
187                         return true;
188                 }
189         }
190         return false;
191 }
192
193 void LightManager::disable_ineffective_light(Device *device, Scene *scene)
194 {
195         /* Make all lights enabled by default, and perform some preliminary checks
196          * needed for finer-tuning of settings (for example, check whether we've
197          * got portals or not).
198          */
199         bool has_portal = false, has_background = false;
200         foreach(Light *light, scene->lights) {
201                 light->is_enabled = light->has_contribution(scene);
202                 has_portal |= light->is_portal;
203                 has_background |= light->type == LIGHT_BACKGROUND;
204         }
205
206         if(has_background) {
207                 /* Ignore background light if:
208                  * - If unsupported on a device
209                  * - If we don't need it (no HDRs etc.)
210                  */
211                 Shader *shader = (scene->background->shader) ? scene->background->shader : scene->default_background;
212                 bool disable_mis = !(has_portal || shader->has_surface_spatial_varying) ||
213                                    !(device->info.advanced_shading);
214                 if(disable_mis) {
215                         VLOG(1) << "Background MIS has been disabled.\n";
216                         foreach(Light *light, scene->lights) {
217                                 if(light->type == LIGHT_BACKGROUND) {
218                                         light->is_enabled = false;
219                                 }
220                         }
221                 }
222         }
223 }
224
225 bool LightManager::object_usable_as_light(Object *object) {
226         Mesh *mesh = object->mesh;
227         /* Skip if we are not visible for BSDFs. */
228         if(!(object->visibility & (PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_TRANSMIT))) {
229                 return false;
230         }
231         /* Skip motion blurred deforming meshes, not supported yet. */
232         if(mesh->has_motion_blur()) {
233                 return false;
234         }
235         /* Skip if we have no emission shaders. */
236         /* TODO(sergey): Ideally we want to avoid such duplicated loop, since it'll
237          * iterate all mesh shaders twice (when counting and when calculating
238          * triangle area.
239          */
240         foreach(const Shader *shader, mesh->used_shaders) {
241                 if(shader->use_mis && shader->has_surface_emission) {
242                         return true;
243                 }
244         }
245         return false;
246 }
247
248 void LightManager::device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
249 {
250         progress.set_status("Updating Lights", "Computing distribution");
251
252         /* count */
253         size_t num_lights = 0;
254         size_t num_portals = 0;
255         size_t num_background_lights = 0;
256         size_t num_triangles = 0;
257
258         bool background_mis = false;
259
260         foreach(Light *light, scene->lights) {
261                 if(light->is_enabled) {
262                         num_lights++;
263                 }
264                 if(light->is_portal) {
265                         num_portals++;
266                 }
267         }
268
269         foreach(Object *object, scene->objects) {
270                 if(progress.get_cancel()) return;
271
272                 if(!object_usable_as_light(object)) {
273                         continue;
274                 }
275                 /* Count triangles. */
276                 Mesh *mesh = object->mesh;
277                 size_t mesh_num_triangles = mesh->num_triangles();
278                 for(size_t i = 0; i < mesh_num_triangles; i++) {
279                         int shader_index = mesh->shader[i];
280                         Shader *shader = (shader_index < mesh->used_shaders.size())
281                                                  ? mesh->used_shaders[shader_index]
282                                                  : scene->default_surface;
283
284                         if(shader->use_mis && shader->has_surface_emission) {
285                                 num_triangles++;
286                         }
287                 }
288         }
289
290         size_t num_distribution = num_triangles + num_lights;
291         VLOG(1) << "Total " << num_distribution << " of light distribution primitives.";
292
293         /* emission area */
294         float4 *distribution = dscene->light_distribution.resize(num_distribution + 1);
295         float totarea = 0.0f;
296
297         /* triangles */
298         size_t offset = 0;
299         int j = 0;
300
301         foreach(Object *object, scene->objects) {
302                 if(progress.get_cancel()) return;
303
304                 if(!object_usable_as_light(object)) {
305                         j++;
306                         continue;
307                 }
308                 /* Sum area. */
309                 Mesh *mesh = object->mesh;
310                 bool transform_applied = mesh->transform_applied;
311                 Transform tfm = object->tfm;
312                 int object_id = j;
313                 int shader_flag = 0;
314
315                 if(!(object->visibility & PATH_RAY_DIFFUSE)) {
316                         shader_flag |= SHADER_EXCLUDE_DIFFUSE;
317                         use_light_visibility = true;
318                 }
319                 if(!(object->visibility & PATH_RAY_GLOSSY)) {
320                         shader_flag |= SHADER_EXCLUDE_GLOSSY;
321                         use_light_visibility = true;
322                 }
323                 if(!(object->visibility & PATH_RAY_TRANSMIT)) {
324                         shader_flag |= SHADER_EXCLUDE_TRANSMIT;
325                         use_light_visibility = true;
326                 }
327                 if(!(object->visibility & PATH_RAY_VOLUME_SCATTER)) {
328                         shader_flag |= SHADER_EXCLUDE_SCATTER;
329                         use_light_visibility = true;
330                 }
331
332                 size_t mesh_num_triangles = mesh->num_triangles();
333                 for(size_t i = 0; i < mesh_num_triangles; i++) {
334                         int shader_index = mesh->shader[i];
335                         Shader *shader = (shader_index < mesh->used_shaders.size())
336                                                  ? mesh->used_shaders[shader_index]
337                                                  : scene->default_surface;
338
339                         if(shader->use_mis && shader->has_surface_emission) {
340                                 distribution[offset].x = totarea;
341                                 distribution[offset].y = __int_as_float(i + mesh->tri_offset);
342                                 distribution[offset].z = __int_as_float(shader_flag);
343                                 distribution[offset].w = __int_as_float(object_id);
344                                 offset++;
345
346                                 Mesh::Triangle t = mesh->get_triangle(i);
347                                 float3 p1 = mesh->verts[t.v[0]];
348                                 float3 p2 = mesh->verts[t.v[1]];
349                                 float3 p3 = mesh->verts[t.v[2]];
350
351                                 if(!transform_applied) {
352                                         p1 = transform_point(&tfm, p1);
353                                         p2 = transform_point(&tfm, p2);
354                                         p3 = transform_point(&tfm, p3);
355                                 }
356
357                                 totarea += triangle_area(p1, p2, p3);
358                         }
359                 }
360
361                 j++;
362         }
363
364         float trianglearea = totarea;
365
366         /* point lights */
367         float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f;
368         bool use_lamp_mis = false;
369
370         int light_index = 0;
371         foreach(Light *light, scene->lights) {
372                 if(!light->is_enabled)
373                         continue;
374
375                 distribution[offset].x = totarea;
376                 distribution[offset].y = __int_as_float(~light_index);
377                 distribution[offset].z = 1.0f;
378                 distribution[offset].w = light->size;
379                 totarea += lightarea;
380
381                 if(light->size > 0.0f && light->use_mis)
382                         use_lamp_mis = true;
383                 if(light->type == LIGHT_BACKGROUND) {
384                         num_background_lights++;
385                         background_mis = light->use_mis;
386                 }
387
388                 light_index++;
389                 offset++;
390         }
391
392         /* normalize cumulative distribution functions */
393         distribution[num_distribution].x = totarea;
394         distribution[num_distribution].y = 0.0f;
395         distribution[num_distribution].z = 0.0f;
396         distribution[num_distribution].w = 0.0f;
397
398         if(totarea > 0.0f) {
399                 for(size_t i = 0; i < num_distribution; i++)
400                         distribution[i].x /= totarea;
401                 distribution[num_distribution].x = 1.0f;
402         }
403
404         if(progress.get_cancel()) return;
405
406         /* update device */
407         KernelIntegrator *kintegrator = &dscene->data.integrator;
408         KernelFilm *kfilm = &dscene->data.film;
409         kintegrator->use_direct_light = (totarea > 0.0f);
410
411         if(kintegrator->use_direct_light) {
412                 /* number of emissives */
413                 kintegrator->num_distribution = num_distribution;
414
415                 /* precompute pdfs */
416                 kintegrator->pdf_triangles = 0.0f;
417                 kintegrator->pdf_lights = 0.0f;
418                 kintegrator->inv_pdf_lights = 0.0f;
419
420                 /* sample one, with 0.5 probability of light or triangle */
421                 kintegrator->num_all_lights = num_lights;
422
423                 if(trianglearea > 0.0f) {
424                         kintegrator->pdf_triangles = 1.0f/trianglearea;
425                         if(num_lights)
426                                 kintegrator->pdf_triangles *= 0.5f;
427                 }
428
429                 if(num_lights) {
430                         kintegrator->pdf_lights = 1.0f/num_lights;
431                         if(trianglearea > 0.0f)
432                                 kintegrator->pdf_lights *= 0.5f;
433
434                         kintegrator->inv_pdf_lights = 1.0f/kintegrator->pdf_lights;
435                 }
436
437                 kintegrator->use_lamp_mis = use_lamp_mis;
438
439                 /* bit of an ugly hack to compensate for emitting triangles influencing
440                  * amount of samples we get for this pass */
441                 kfilm->pass_shadow_scale = 1.0f;
442
443                 if(kintegrator->pdf_triangles != 0.0f)
444                         kfilm->pass_shadow_scale *= 0.5f;
445
446                 if(num_background_lights < num_lights)
447                         kfilm->pass_shadow_scale *= (float)(num_lights - num_background_lights)/(float)num_lights;
448
449                 /* CDF */
450                 device->tex_alloc("__light_distribution", dscene->light_distribution);
451
452                 /* Portals */
453                 if(num_portals > 0) {
454                         kintegrator->portal_offset = light_index;
455                         kintegrator->num_portals = num_portals;
456                         kintegrator->portal_pdf = background_mis? 0.5f: 1.0f;
457                 }
458                 else {
459                         kintegrator->num_portals = 0;
460                         kintegrator->portal_offset = 0;
461                         kintegrator->portal_pdf = 0.0f;
462                 }
463         }
464         else {
465                 dscene->light_distribution.clear();
466
467                 kintegrator->num_distribution = 0;
468                 kintegrator->num_all_lights = 0;
469                 kintegrator->pdf_triangles = 0.0f;
470                 kintegrator->pdf_lights = 0.0f;
471                 kintegrator->inv_pdf_lights = 0.0f;
472                 kintegrator->use_lamp_mis = false;
473                 kintegrator->num_portals = 0;
474                 kintegrator->portal_offset = 0;
475                 kintegrator->portal_pdf = 0.0f;
476
477                 kfilm->pass_shadow_scale = 1.0f;
478         }
479 }
480
481 static void background_cdf(int start,
482                            int end,
483                            int res,
484                            int cdf_count,
485                            const vector<float3> *pixels,
486                            float2 *cond_cdf)
487 {
488         /* Conditional CDFs (rows, U direction). */
489         /* NOTE: It is possible to have some NaN pixels on background
490          * which will ruin CDF causing wrong shading. We replace such
491          * pixels with black.
492          */
493         for(int i = start; i < end; i++) {
494                 float sin_theta = sinf(M_PI_F * (i + 0.5f) / res);
495                 float3 env_color = (*pixels)[i * res];
496                 float ave_luminance = average(env_color);
497                 /* TODO(sergey): Consider adding average_safe(). */
498                 if(!isfinite(ave_luminance)) {
499                         ave_luminance = 0.0f;
500                 }
501
502                 cond_cdf[i * cdf_count].x = ave_luminance * sin_theta;
503                 cond_cdf[i * cdf_count].y = 0.0f;
504
505                 for(int j = 1; j < res; j++) {
506                         env_color = (*pixels)[i * res + j];
507                         ave_luminance = average(env_color);
508                         if(!isfinite(ave_luminance)) {
509                                 ave_luminance = 0.0f;
510                         }
511
512                         cond_cdf[i * cdf_count + j].x = ave_luminance * sin_theta;
513                         cond_cdf[i * cdf_count + j].y = cond_cdf[i * cdf_count + j - 1].y + cond_cdf[i * cdf_count + j - 1].x / res;
514                 }
515
516                 float cdf_total = cond_cdf[i * cdf_count + res - 1].y + cond_cdf[i * cdf_count + res - 1].x / res;
517                 float cdf_total_inv = 1.0f / cdf_total;
518
519                 /* stuff the total into the brightness value for the last entry, because
520                  * we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
521                 cond_cdf[i * cdf_count + res].x = cdf_total;
522
523                 if(cdf_total > 0.0f)
524                         for(int j = 1; j < res; j++)
525                                 cond_cdf[i * cdf_count + j].y *= cdf_total_inv;
526
527                 cond_cdf[i * cdf_count + res].y = 1.0f;
528         }
529 }
530
531 void LightManager::device_update_background(Device *device,
532                                             DeviceScene *dscene,
533                                             Scene *scene,
534                                             Progress& progress)
535 {
536         KernelIntegrator *kintegrator = &dscene->data.integrator;
537         Light *background_light = NULL;
538
539         /* find background light */
540         foreach(Light *light, scene->lights) {
541                 if(light->type == LIGHT_BACKGROUND) {
542                         background_light = light;
543                         break;
544                 }
545         }
546
547         /* no background light found, signal renderer to skip sampling */
548         if(!background_light || !background_light->is_enabled) {
549                 kintegrator->pdf_background_res = 0;
550                 return;
551         }
552
553         progress.set_status("Updating Lights", "Importance map");
554
555         assert(kintegrator->use_direct_light);
556
557         /* get the resolution from the light's size (we stuff it in there) */
558         int res = background_light->map_resolution;
559         kintegrator->pdf_background_res = res;
560
561         assert(res > 0);
562
563         vector<float3> pixels;
564         shade_background_pixels(device, dscene, res, pixels, progress);
565
566         if(progress.get_cancel())
567                 return;
568
569         /* build row distributions and column distribution for the infinite area environment light */
570         int cdf_count = res + 1;
571         float2 *marg_cdf = dscene->light_background_marginal_cdf.resize(cdf_count);
572         float2 *cond_cdf = dscene->light_background_conditional_cdf.resize(cdf_count * cdf_count);
573
574         double time_start = time_dt();
575         if(res < 512) {
576                 /* Small enough resolution, faster to do single-threaded. */
577                 background_cdf(0, res, res, cdf_count, &pixels, cond_cdf);
578         }
579         else {
580                 /* Threaded evaluation for large resolution. */
581                 const int num_blocks = TaskScheduler::num_threads();
582                 const int chunk_size = res / num_blocks;
583                 int start_row = 0;
584                 TaskPool pool;
585                 for(int i = 0; i < num_blocks; ++i) {
586                         const int current_chunk_size =
587                             (i != num_blocks - 1) ? chunk_size
588                                                   : (res - i * chunk_size);
589                         pool.push(function_bind(&background_cdf,
590                                                 start_row, start_row + current_chunk_size,
591                                                 res,
592                                                 cdf_count,
593                                                 &pixels,
594                                                 cond_cdf));
595                         start_row += current_chunk_size;
596                 }
597                 pool.wait_work();
598         }
599
600         /* marginal CDFs (column, V direction, sum of rows) */
601         marg_cdf[0].x = cond_cdf[res].x;
602         marg_cdf[0].y = 0.0f;
603
604         for(int i = 1; i < res; i++) {
605                 marg_cdf[i].x = cond_cdf[i * cdf_count + res].x;
606                 marg_cdf[i].y = marg_cdf[i - 1].y + marg_cdf[i - 1].x / res;
607         }
608
609         float cdf_total = marg_cdf[res - 1].y + marg_cdf[res - 1].x / res;
610         marg_cdf[res].x = cdf_total;
611
612         if(cdf_total > 0.0f)
613                 for(int i = 1; i < res; i++)
614                         marg_cdf[i].y /= cdf_total;
615
616         marg_cdf[res].y = 1.0f;
617
618         VLOG(2) << "Background MIS build time " << time_dt() - time_start << "\n";
619
620         /* update device */
621         device->tex_alloc("__light_background_marginal_cdf", dscene->light_background_marginal_cdf);
622         device->tex_alloc("__light_background_conditional_cdf", dscene->light_background_conditional_cdf);
623 }
624
625 void LightManager::device_update_points(Device *device,
626                                         DeviceScene *dscene,
627                                         Scene *scene)
628 {
629         int num_scene_lights = scene->lights.size();
630
631         int num_lights = 0;
632         foreach(Light *light, scene->lights) {
633                 if(light->is_enabled || light->is_portal) {
634                         num_lights++;
635                 }
636         }
637
638         float4 *light_data = dscene->light_data.resize(num_lights*LIGHT_SIZE);
639
640         if(num_lights == 0) {
641                 VLOG(1) << "No effective light, ignoring points update.";
642                 return;
643         }
644
645         int light_index = 0;
646
647         foreach(Light *light, scene->lights) {
648                 if(!light->is_enabled) {
649                         continue;
650                 }
651
652                 float3 co = light->co;
653                 Shader *shader = (light->shader) ? light->shader : scene->default_light;
654                 int shader_id = scene->shader_manager->get_shader_id(shader);
655                 float samples = __int_as_float(light->samples);
656                 float max_bounces = __int_as_float(light->max_bounces);
657
658                 if(!light->cast_shadow)
659                         shader_id &= ~SHADER_CAST_SHADOW;
660
661                 if(!light->use_diffuse) {
662                         shader_id |= SHADER_EXCLUDE_DIFFUSE;
663                         use_light_visibility = true;
664                 }
665                 if(!light->use_glossy) {
666                         shader_id |= SHADER_EXCLUDE_GLOSSY;
667                         use_light_visibility = true;
668                 }
669                 if(!light->use_transmission) {
670                         shader_id |= SHADER_EXCLUDE_TRANSMIT;
671                         use_light_visibility = true;
672                 }
673                 if(!light->use_scatter) {
674                         shader_id |= SHADER_EXCLUDE_SCATTER;
675                         use_light_visibility = true;
676                 }
677
678                 if(light->type == LIGHT_POINT) {
679                         shader_id &= ~SHADER_AREA_LIGHT;
680
681                         float radius = light->size;
682                         float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f;
683
684                         if(light->use_mis && radius > 0.0f)
685                                 shader_id |= SHADER_USE_MIS;
686
687                         light_data[light_index*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
688                         light_data[light_index*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, 0.0f);
689                         light_data[light_index*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
690                         light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
691                 }
692                 else if(light->type == LIGHT_DISTANT) {
693                         shader_id &= ~SHADER_AREA_LIGHT;
694
695                         float radius = light->size;
696                         float angle = atanf(radius);
697                         float cosangle = cosf(angle);
698                         float area = M_PI_F*radius*radius;
699                         float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
700                         float3 dir = light->dir;
701
702                         dir = safe_normalize(dir);
703
704                         if(light->use_mis && area > 0.0f)
705                                 shader_id |= SHADER_USE_MIS;
706
707                         light_data[light_index*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), dir.x, dir.y, dir.z);
708                         light_data[light_index*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, cosangle, invarea);
709                         light_data[light_index*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
710                         light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
711                 }
712                 else if(light->type == LIGHT_BACKGROUND) {
713                         uint visibility = scene->background->visibility;
714
715                         shader_id &= ~SHADER_AREA_LIGHT;
716                         shader_id |= SHADER_USE_MIS;
717
718                         if(!(visibility & PATH_RAY_DIFFUSE)) {
719                                 shader_id |= SHADER_EXCLUDE_DIFFUSE;
720                                 use_light_visibility = true;
721                         }
722                         if(!(visibility & PATH_RAY_GLOSSY)) {
723                                 shader_id |= SHADER_EXCLUDE_GLOSSY;
724                                 use_light_visibility = true;
725                         }
726                         if(!(visibility & PATH_RAY_TRANSMIT)) {
727                                 shader_id |= SHADER_EXCLUDE_TRANSMIT;
728                                 use_light_visibility = true;
729                         }
730                         if(!(visibility & PATH_RAY_VOLUME_SCATTER)) {
731                                 shader_id |= SHADER_EXCLUDE_SCATTER;
732                                 use_light_visibility = true;
733                         }
734
735                         light_data[light_index*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), 0.0f, 0.0f, 0.0f);
736                         light_data[light_index*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f);
737                         light_data[light_index*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
738                         light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
739                 }
740                 else if(light->type == LIGHT_AREA) {
741                         float3 axisu = light->axisu*(light->sizeu*light->size);
742                         float3 axisv = light->axisv*(light->sizev*light->size);
743                         float area = len(axisu)*len(axisv);
744                         float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
745                         float3 dir = light->dir;
746                         
747                         dir = safe_normalize(dir);
748
749                         if(light->use_mis && area > 0.0f)
750                                 shader_id |= SHADER_USE_MIS;
751
752                         light_data[light_index*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
753                         light_data[light_index*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z);
754                         light_data[light_index*LIGHT_SIZE + 2] = make_float4(invarea, axisv.x, axisv.y, axisv.z);
755                         light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z);
756                 }
757                 else if(light->type == LIGHT_SPOT) {
758                         shader_id &= ~SHADER_AREA_LIGHT;
759
760                         float radius = light->size;
761                         float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f;
762                         float spot_angle = cosf(light->spot_angle*0.5f);
763                         float spot_smooth = (1.0f - spot_angle)*light->spot_smooth;
764                         float3 dir = light->dir;
765                         
766                         dir = safe_normalize(dir);
767
768                         if(light->use_mis && radius > 0.0f)
769                                 shader_id |= SHADER_USE_MIS;
770
771                         light_data[light_index*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
772                         light_data[light_index*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, spot_angle);
773                         light_data[light_index*LIGHT_SIZE + 2] = make_float4(spot_smooth, dir.x, dir.y, dir.z);
774                         light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
775                 }
776
777                 light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f);
778
779                 Transform tfm = light->tfm;
780                 Transform itfm = transform_inverse(tfm);
781                 memcpy(&light_data[light_index*LIGHT_SIZE + 5], &tfm, sizeof(float4)*3);
782                 memcpy(&light_data[light_index*LIGHT_SIZE + 8], &itfm, sizeof(float4)*3);
783
784                 light_index++;
785         }
786
787         /* TODO(sergey): Consider moving portals update to their own function
788          * keeping this one more manageable.
789          */
790         foreach(Light *light, scene->lights) {
791                 if(!light->is_portal)
792                         continue;
793                 assert(light->type == LIGHT_AREA);
794
795                 float3 co = light->co;
796                 float3 axisu = light->axisu*(light->sizeu*light->size);
797                 float3 axisv = light->axisv*(light->sizev*light->size);
798                 float area = len(axisu)*len(axisv);
799                 float invarea = (area > 0.0f) ? 1.0f / area : 1.0f;
800                 float3 dir = light->dir;
801
802                 dir = safe_normalize(dir);
803
804                 light_data[light_index*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
805                 light_data[light_index*LIGHT_SIZE + 1] = make_float4(area, axisu.x, axisu.y, axisu.z);
806                 light_data[light_index*LIGHT_SIZE + 2] = make_float4(invarea, axisv.x, axisv.y, axisv.z);
807                 light_data[light_index*LIGHT_SIZE + 3] = make_float4(-1, dir.x, dir.y, dir.z);
808                 light_data[light_index*LIGHT_SIZE + 4] = make_float4(-1, 0.0f, 0.0f, 0.0f);
809
810                 Transform tfm = light->tfm;
811                 Transform itfm = transform_inverse(tfm);
812                 memcpy(&light_data[light_index*LIGHT_SIZE + 5], &tfm, sizeof(float4)*3);
813                 memcpy(&light_data[light_index*LIGHT_SIZE + 8], &itfm, sizeof(float4)*3);
814
815                 light_index++;
816         }
817
818         VLOG(1) << "Number of lights sent to the device: " << light_index;
819
820         VLOG(1) << "Number of lights without contribution: "
821                 << num_scene_lights - light_index;
822
823         device->tex_alloc("__light_data", dscene->light_data);
824 }
825
826 void LightManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
827 {
828         if(!need_update)
829                 return;
830
831         VLOG(1) << "Total " << scene->lights.size() << " lights.";
832
833         device_free(device, dscene);
834
835         use_light_visibility = false;
836
837         disable_ineffective_light(device, scene);
838
839         device_update_points(device, dscene, scene);
840         if(progress.get_cancel()) return;
841
842         device_update_distribution(device, dscene, scene, progress);
843         if(progress.get_cancel()) return;
844
845         device_update_background(device, dscene, scene, progress);
846         if(progress.get_cancel()) return;
847
848         if(use_light_visibility != scene->film->use_light_visibility) {
849                 scene->film->use_light_visibility = use_light_visibility;
850                 scene->film->tag_update(scene);
851         }
852
853         need_update = false;
854 }
855
856 void LightManager::device_free(Device *device, DeviceScene *dscene)
857 {
858         device->tex_free(dscene->light_distribution);
859         device->tex_free(dscene->light_data);
860         device->tex_free(dscene->light_background_marginal_cdf);
861         device->tex_free(dscene->light_background_conditional_cdf);
862
863         dscene->light_distribution.clear();
864         dscene->light_data.clear();
865         dscene->light_background_marginal_cdf.clear();
866         dscene->light_background_conditional_cdf.clear();
867 }
868
869 void LightManager::tag_update(Scene * /*scene*/)
870 {
871         need_update = true;
872 }
873
874 CCL_NAMESPACE_END
875