Cycles/Eevee: unify light strength and color
[blender.git] / intern / cycles / blender / blender_object.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/camera.h"
18 #include "render/integrator.h"
19 #include "render/graph.h"
20 #include "render/light.h"
21 #include "render/mesh.h"
22 #include "render/object.h"
23 #include "render/scene.h"
24 #include "render/nodes.h"
25 #include "render/particles.h"
26 #include "render/shader.h"
27
28 #include "blender/blender_object_cull.h"
29 #include "blender/blender_sync.h"
30 #include "blender/blender_util.h"
31
32 #include "util/util_foreach.h"
33 #include "util/util_hash.h"
34 #include "util/util_logging.h"
35
36 CCL_NAMESPACE_BEGIN
37
38 /* Utilities */
39
40 bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
41 {
42   /* test if we can instance or if the object is modified */
43   if (b_ob.type() == BL::Object::type_META) {
44     /* multi-user and dupli metaballs are fused, can't instance */
45     return true;
46   }
47   else if (ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
48     /* modifiers */
49     return true;
50   }
51   else {
52     /* object level material links */
53     BL::Object::material_slots_iterator slot;
54     for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
55       if (slot->link() == BL::MaterialSlot::link_OBJECT)
56         return true;
57   }
58
59   return false;
60 }
61
62 bool BlenderSync::object_is_mesh(BL::Object &b_ob)
63 {
64   BL::ID b_ob_data = b_ob.data();
65
66   if (!b_ob_data) {
67     return false;
68   }
69
70   if (b_ob.type() == BL::Object::type_CURVE) {
71     /* Skip exporting curves without faces, overhead can be
72      * significant if there are many for path animation. */
73     BL::Curve b_curve(b_ob.data());
74
75     return (b_curve.bevel_object() || b_curve.extrude() != 0.0f || b_curve.bevel_depth() != 0.0f ||
76             b_curve.dimensions() == BL::Curve::dimensions_2D || b_ob.modifiers.length());
77   }
78   else {
79     return (b_ob_data.is_a(&RNA_Mesh) || b_ob_data.is_a(&RNA_Curve) ||
80             b_ob_data.is_a(&RNA_MetaBall));
81   }
82 }
83
84 bool BlenderSync::object_is_light(BL::Object &b_ob)
85 {
86   BL::ID b_ob_data = b_ob.data();
87
88   return (b_ob_data && b_ob_data.is_a(&RNA_Light));
89 }
90
91 static uint object_ray_visibility(BL::Object &b_ob)
92 {
93   PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility");
94   uint flag = 0;
95
96   flag |= get_boolean(cvisibility, "camera") ? PATH_RAY_CAMERA : 0;
97   flag |= get_boolean(cvisibility, "diffuse") ? PATH_RAY_DIFFUSE : 0;
98   flag |= get_boolean(cvisibility, "glossy") ? PATH_RAY_GLOSSY : 0;
99   flag |= get_boolean(cvisibility, "transmission") ? PATH_RAY_TRANSMIT : 0;
100   flag |= get_boolean(cvisibility, "shadow") ? PATH_RAY_SHADOW : 0;
101   flag |= get_boolean(cvisibility, "scatter") ? PATH_RAY_VOLUME_SCATTER : 0;
102
103   return flag;
104 }
105
106 /* Light */
107
108 void BlenderSync::sync_light(BL::Object &b_parent,
109                              int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
110                              BL::Object &b_ob,
111                              BL::Object &b_ob_instance,
112                              int random_id,
113                              Transform &tfm,
114                              bool *use_portal)
115 {
116   /* test if we need to sync */
117   Light *light;
118   ObjectKey key(b_parent, persistent_id, b_ob_instance);
119
120   if (!light_map.sync(&light, b_ob, b_parent, key)) {
121     if (light->is_portal)
122       *use_portal = true;
123     return;
124   }
125
126   BL::Light b_light(b_ob.data());
127
128   /* type */
129   switch (b_light.type()) {
130     case BL::Light::type_POINT: {
131       BL::PointLight b_point_light(b_light);
132       light->size = b_point_light.shadow_soft_size();
133       light->type = LIGHT_POINT;
134       break;
135     }
136     case BL::Light::type_SPOT: {
137       BL::SpotLight b_spot_light(b_light);
138       light->size = b_spot_light.shadow_soft_size();
139       light->type = LIGHT_SPOT;
140       light->spot_angle = b_spot_light.spot_size();
141       light->spot_smooth = b_spot_light.spot_blend();
142       break;
143     }
144     /* Hemi were removed from 2.8 */
145     // case BL::Light::type_HEMI: {
146     //  light->type = LIGHT_DISTANT;
147     //  light->size = 0.0f;
148     //  break;
149     // }
150     case BL::Light::type_SUN: {
151       BL::SunLight b_sun_light(b_light);
152       light->size = b_sun_light.shadow_soft_size();
153       light->type = LIGHT_DISTANT;
154       break;
155     }
156     case BL::Light::type_AREA: {
157       BL::AreaLight b_area_light(b_light);
158       light->size = 1.0f;
159       light->axisu = transform_get_column(&tfm, 0);
160       light->axisv = transform_get_column(&tfm, 1);
161       light->sizeu = b_area_light.size();
162       switch (b_area_light.shape()) {
163         case BL::AreaLight::shape_SQUARE:
164           light->sizev = light->sizeu;
165           light->round = false;
166           break;
167         case BL::AreaLight::shape_RECTANGLE:
168           light->sizev = b_area_light.size_y();
169           light->round = false;
170           break;
171         case BL::AreaLight::shape_DISK:
172           light->sizev = light->sizeu;
173           light->round = true;
174           break;
175         case BL::AreaLight::shape_ELLIPSE:
176           light->sizev = b_area_light.size_y();
177           light->round = true;
178           break;
179       }
180       light->type = LIGHT_AREA;
181       break;
182     }
183   }
184
185   /* strength */
186   light->strength = get_float3(b_light.color());
187   light->strength *= BL::PointLight(b_light).energy();
188
189   /* location and (inverted!) direction */
190   light->co = transform_get_column(&tfm, 3);
191   light->dir = -transform_get_column(&tfm, 2);
192   light->tfm = tfm;
193
194   /* shader */
195   vector<Shader *> used_shaders;
196   find_shader(b_light, used_shaders, scene->default_light);
197   light->shader = used_shaders[0];
198
199   /* shadow */
200   PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
201   PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles");
202   light->cast_shadow = get_boolean(clight, "cast_shadow");
203   light->use_mis = get_boolean(clight, "use_multiple_importance_sampling");
204
205   int samples = get_int(clight, "samples");
206   if (get_boolean(cscene, "use_square_samples"))
207     light->samples = samples * samples;
208   else
209     light->samples = samples;
210
211   light->max_bounces = get_int(clight, "max_bounces");
212
213   if (b_ob != b_ob_instance) {
214     light->random_id = random_id;
215   }
216   else {
217     light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0);
218   }
219
220   if (light->type == LIGHT_AREA)
221     light->is_portal = get_boolean(clight, "is_portal");
222   else
223     light->is_portal = false;
224
225   if (light->is_portal)
226     *use_portal = true;
227
228   /* visibility */
229   uint visibility = object_ray_visibility(b_ob);
230   light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0;
231   light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0;
232   light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0;
233   light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0;
234
235   /* tag */
236   light->tag_update(scene);
237 }
238
239 void BlenderSync::sync_background_light(bool use_portal)
240 {
241   BL::World b_world = b_scene.world();
242
243   if (b_world) {
244     PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
245     PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
246
247     enum SamplingMethod { SAMPLING_NONE = 0, SAMPLING_AUTOMATIC, SAMPLING_MANUAL, SAMPLING_NUM };
248     int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC);
249     bool sample_as_light = (sampling_method != SAMPLING_NONE);
250
251     if (sample_as_light || use_portal) {
252       /* test if we need to sync */
253       Light *light;
254       ObjectKey key(b_world, 0, b_world);
255
256       if (light_map.sync(&light, b_world, b_world, key) || world_recalc ||
257           b_world.ptr.data != world_map) {
258         light->type = LIGHT_BACKGROUND;
259         if (sampling_method == SAMPLING_MANUAL) {
260           light->map_resolution = get_int(cworld, "sample_map_resolution");
261         }
262         else {
263           light->map_resolution = 0;
264         }
265         light->shader = scene->default_background;
266         light->use_mis = sample_as_light;
267         light->max_bounces = get_int(cworld, "max_bounces");
268
269         int samples = get_int(cworld, "samples");
270         if (get_boolean(cscene, "use_square_samples"))
271           light->samples = samples * samples;
272         else
273           light->samples = samples;
274
275         light->tag_update(scene);
276         light_map.set_recalc(b_world);
277       }
278     }
279   }
280
281   world_map = b_world.ptr.data;
282   world_recalc = false;
283 }
284
285 /* Object */
286
287 Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
288                                  BL::ViewLayer &b_view_layer,
289                                  BL::DepsgraphObjectInstance &b_instance,
290                                  float motion_time,
291                                  bool show_self,
292                                  bool show_particles,
293                                  BlenderObjectCulling &culling,
294                                  bool *use_portal)
295 {
296   const bool is_instance = b_instance.is_instance();
297   BL::Object b_ob = b_instance.object();
298   BL::Object b_parent = is_instance ? b_instance.parent() : b_instance.object();
299   BL::Object b_ob_instance = is_instance ? b_instance.instance_object() : b_ob;
300   const bool motion = motion_time != 0.0f;
301   /*const*/ Transform tfm = get_transform(b_ob.matrix_world());
302   int *persistent_id = NULL;
303   BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
304   if (is_instance) {
305     persistent_id_array = b_instance.persistent_id();
306     persistent_id = persistent_id_array.data;
307   }
308
309   /* light is handled separately */
310   if (!motion && object_is_light(b_ob)) {
311     /* TODO: don't use lights for excluded layers used as mask layer,
312      * when dynamic overrides are back. */
313 #if 0
314     if (!((layer_flag & view_layer.holdout_layer) && (layer_flag & view_layer.exclude_layer)))
315 #endif
316     {
317       sync_light(b_parent,
318                  persistent_id,
319                  b_ob,
320                  b_ob_instance,
321                  is_instance ? b_instance.random_id() : 0,
322                  tfm,
323                  use_portal);
324     }
325
326     return NULL;
327   }
328
329   /* only interested in object that we can create meshes from */
330   if (!object_is_mesh(b_ob)) {
331     return NULL;
332   }
333
334   /* Perform object culling. */
335   if (culling.test(scene, b_ob, tfm)) {
336     return NULL;
337   }
338
339   /* Visibility flags for both parent and child. */
340   PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
341   bool use_holdout = get_boolean(cobject, "is_holdout") ||
342                      b_parent.holdout_get(PointerRNA_NULL, b_view_layer);
343   uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
344
345   if (b_parent.ptr.data != b_ob.ptr.data) {
346     visibility &= object_ray_visibility(b_parent);
347   }
348
349   /* TODO: make holdout objects on excluded layer invisible for non-camera rays. */
350 #if 0
351   if (use_holdout && (layer_flag & view_layer.exclude_layer)) {
352     visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA);
353   }
354 #endif
355
356   /* Clear camera visibility for indirect only objects. */
357   bool use_indirect_only = b_parent.indirect_only_get(PointerRNA_NULL, b_view_layer);
358   if (use_indirect_only) {
359     visibility &= ~PATH_RAY_CAMERA;
360   }
361
362   /* Don't export completely invisible objects. */
363   if (visibility == 0) {
364     return NULL;
365   }
366
367   /* key to lookup object */
368   ObjectKey key(b_parent, persistent_id, b_ob_instance);
369   Object *object;
370
371   /* motion vector case */
372   if (motion) {
373     object = object_map.find(key);
374
375     if (object && object->use_motion()) {
376       /* Set transform at matching motion time step. */
377       int time_index = object->motion_step(motion_time);
378       if (time_index >= 0) {
379         object->motion[time_index] = tfm;
380       }
381
382       /* mesh deformation */
383       if (object->mesh)
384         sync_mesh_motion(b_depsgraph, b_ob, object, motion_time);
385     }
386
387     return object;
388   }
389
390   /* test if we need to sync */
391   bool object_updated = false;
392
393   if (object_map.sync(&object, b_ob, b_parent, key))
394     object_updated = true;
395
396   /* mesh sync */
397   object->mesh = sync_mesh(
398       b_depsgraph, b_ob, b_ob_instance, object_updated, show_self, show_particles);
399
400   /* special case not tracked by object update flags */
401
402   /* holdout */
403   if (use_holdout != object->use_holdout) {
404     object->use_holdout = use_holdout;
405     scene->object_manager->tag_update(scene);
406     object_updated = true;
407   }
408
409   if (visibility != object->visibility) {
410     object->visibility = visibility;
411     object_updated = true;
412   }
413
414   bool is_shadow_catcher = get_boolean(cobject, "is_shadow_catcher");
415   if (is_shadow_catcher != object->is_shadow_catcher) {
416     object->is_shadow_catcher = is_shadow_catcher;
417     object_updated = true;
418   }
419
420   /* sync the asset name for Cryptomatte */
421   BL::Object parent = b_ob.parent();
422   ustring parent_name;
423   if (parent) {
424     while (parent.parent()) {
425       parent = parent.parent();
426     }
427     parent_name = parent.name();
428   }
429   else {
430     parent_name = b_ob.name();
431   }
432   if (object->asset_name != parent_name) {
433     object->asset_name = parent_name;
434     object_updated = true;
435   }
436
437   /* object sync
438    * transform comparison should not be needed, but duplis don't work perfect
439    * in the depsgraph and may not signal changes, so this is a workaround */
440   if (object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) {
441     object->name = b_ob.name().c_str();
442     object->pass_id = b_ob.pass_index();
443     object->tfm = tfm;
444     object->motion.clear();
445
446     /* motion blur */
447     Scene::MotionType need_motion = scene->need_motion();
448     if (need_motion != Scene::MOTION_NONE && object->mesh) {
449       Mesh *mesh = object->mesh;
450       mesh->use_motion_blur = false;
451       mesh->motion_steps = 0;
452
453       uint motion_steps;
454
455       if (need_motion == Scene::MOTION_BLUR) {
456         motion_steps = object_motion_steps(b_parent, b_ob);
457         mesh->motion_steps = motion_steps;
458         if (motion_steps && object_use_deform_motion(b_parent, b_ob)) {
459           mesh->use_motion_blur = true;
460         }
461       }
462       else {
463         motion_steps = 3;
464         mesh->motion_steps = motion_steps;
465       }
466
467       object->motion.clear();
468       object->motion.resize(motion_steps, transform_empty());
469
470       if (motion_steps) {
471         object->motion[motion_steps / 2] = tfm;
472
473         for (size_t step = 0; step < motion_steps; step++) {
474           motion_times.insert(object->motion_time(step));
475         }
476       }
477     }
478
479     /* dupli texture coordinates and random_id */
480     if (is_instance) {
481       object->dupli_generated = 0.5f * get_float3(b_instance.orco()) -
482                                 make_float3(0.5f, 0.5f, 0.5f);
483       object->dupli_uv = get_float2(b_instance.uv());
484       object->random_id = b_instance.random_id();
485     }
486     else {
487       object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
488       object->dupli_uv = make_float2(0.0f, 0.0f);
489       object->random_id = hash_int_2d(hash_string(object->name.c_str()), 0);
490     }
491
492     object->tag_update(scene);
493   }
494
495   if (is_instance) {
496     /* Sync possible particle data. */
497     sync_dupli_particle(b_parent, b_instance, object);
498   }
499
500   return object;
501 }
502
503 /* Object Loop */
504
505 void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, float motion_time)
506 {
507   /* layer data */
508   bool motion = motion_time != 0.0f;
509
510   if (!motion) {
511     /* prepare for sync */
512     light_map.pre_sync();
513     mesh_map.pre_sync();
514     object_map.pre_sync();
515     particle_system_map.pre_sync();
516     motion_times.clear();
517   }
518   else {
519     mesh_motion_synced.clear();
520   }
521
522   /* initialize culling */
523   BlenderObjectCulling culling(scene, b_scene);
524
525   /* object loop */
526   bool cancel = false;
527   bool use_portal = false;
528
529   BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
530
531   BL::Depsgraph::object_instances_iterator b_instance_iter;
532   for (b_depsgraph.object_instances.begin(b_instance_iter);
533        b_instance_iter != b_depsgraph.object_instances.end() && !cancel;
534        ++b_instance_iter) {
535     BL::DepsgraphObjectInstance b_instance = *b_instance_iter;
536     BL::Object b_ob = b_instance.object();
537
538     /* load per-object culling data */
539     culling.init_object(scene, b_ob);
540
541     /* test if object needs to be hidden */
542     const bool show_self = b_instance.show_self();
543     const bool show_particles = b_instance.show_particles();
544
545     if (show_self || show_particles) {
546       /* object itself */
547       sync_object(b_depsgraph,
548                   b_view_layer,
549                   b_instance,
550                   motion_time,
551                   show_self,
552                   show_particles,
553                   culling,
554                   &use_portal);
555     }
556
557     cancel = progress.get_cancel();
558   }
559
560   progress.set_sync_status("");
561
562   if (!cancel && !motion) {
563     sync_background_light(use_portal);
564
565     /* handle removed data and modified pointers */
566     if (light_map.post_sync())
567       scene->light_manager->tag_update(scene);
568     if (mesh_map.post_sync())
569       scene->mesh_manager->tag_update(scene);
570     if (object_map.post_sync())
571       scene->object_manager->tag_update(scene);
572     if (particle_system_map.post_sync())
573       scene->particle_system_manager->tag_update(scene);
574   }
575
576   if (motion)
577     mesh_motion_synced.clear();
578 }
579
580 void BlenderSync::sync_motion(BL::RenderSettings &b_render,
581                               BL::Depsgraph &b_depsgraph,
582                               BL::Object &b_override,
583                               int width,
584                               int height,
585                               void **python_thread_state)
586 {
587   if (scene->need_motion() == Scene::MOTION_NONE)
588     return;
589
590   /* get camera object here to deal with camera switch */
591   BL::Object b_cam = b_scene.camera();
592   if (b_override)
593     b_cam = b_override;
594
595   Camera prevcam = *(scene->camera);
596
597   int frame_center = b_scene.frame_current();
598   float subframe_center = b_scene.frame_subframe();
599   float frame_center_delta = 0.0f;
600
601   if (scene->need_motion() != Scene::MOTION_PASS &&
602       scene->camera->motion_position != Camera::MOTION_POSITION_CENTER) {
603     float shuttertime = scene->camera->shuttertime;
604     if (scene->camera->motion_position == Camera::MOTION_POSITION_END) {
605       frame_center_delta = -shuttertime * 0.5f;
606     }
607     else {
608       assert(scene->camera->motion_position == Camera::MOTION_POSITION_START);
609       frame_center_delta = shuttertime * 0.5f;
610     }
611
612     float time = frame_center + subframe_center + frame_center_delta;
613     int frame = (int)floorf(time);
614     float subframe = time - frame;
615     python_thread_state_restore(python_thread_state);
616     b_engine.frame_set(frame, subframe);
617     python_thread_state_save(python_thread_state);
618     sync_camera_motion(b_render, b_cam, width, height, 0.0f);
619     sync_objects(b_depsgraph, 0.0f);
620   }
621
622   /* always sample these times for camera motion */
623   motion_times.insert(-1.0f);
624   motion_times.insert(1.0f);
625
626   /* note iteration over motion_times set happens in sorted order */
627   foreach (float relative_time, motion_times) {
628     /* center time is already handled. */
629     if (relative_time == 0.0f) {
630       continue;
631     }
632
633     VLOG(1) << "Synchronizing motion for the relative time " << relative_time << ".";
634
635     /* fixed shutter time to get previous and next frame for motion pass */
636     float shuttertime = scene->motion_shutter_time();
637
638     /* compute frame and subframe time */
639     float time = frame_center + subframe_center + frame_center_delta +
640                  relative_time * shuttertime * 0.5f;
641     int frame = (int)floorf(time);
642     float subframe = time - frame;
643
644     /* change frame */
645     python_thread_state_restore(python_thread_state);
646     b_engine.frame_set(frame, subframe);
647     python_thread_state_save(python_thread_state);
648
649     /* sync camera, only supports two times at the moment */
650     if (relative_time == -1.0f || relative_time == 1.0f) {
651       sync_camera_motion(b_render, b_cam, width, height, relative_time);
652     }
653
654     /* sync object */
655     sync_objects(b_depsgraph, relative_time);
656   }
657
658   /* we need to set the python thread state again because this
659    * function assumes it is being executed from python and will
660    * try to save the thread state */
661   python_thread_state_restore(python_thread_state);
662   b_engine.frame_set(frame_center, subframe_center);
663   python_thread_state_save(python_thread_state);
664
665   /* tag camera for motion update */
666   if (scene->camera->motion_modified(prevcam))
667     scene->camera->tag_update();
668 }
669
670 CCL_NAMESPACE_END