2011-04-27 11:58:34 +00:00
|
|
|
/*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Copyright 2011-2013 Blender Foundation
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2011-04-27 11:58:34 +00:00
|
|
|
*
|
2013-08-18 14:16:15 +00:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
2014-12-25 02:50:24 +01:00
|
|
|
* limitations under the License.
|
2011-04-27 11:58:34 +00:00
|
|
|
*/
|
|
|
|
|
Cycles: Make all #include statements relative to cycles source directory
The idea is to make include statements more explicit and obvious where the
file is coming from, additionally reducing chance of wrong header being
picked up.
For example, it was not obvious whether bvh.h was refferring to builder
or traversal, whenter node.h is a generic graph node or a shader node
and cases like that.
Surely this might look obvious for the active developers, but after some
time of not touching the code it becomes less obvious where file is coming
from.
This was briefly mentioned in T50824 and seems @brecht is fine with such
explicitness, but need to agree with all active developers before committing
this.
Please note that this patch is lacking changes related on GPU/OpenCL
support. This will be solved if/when we all agree this is a good idea to move
forward.
Reviewers: brecht, lukasstockner97, maiself, nirved, dingto, juicyfruit, swerner
Reviewed By: lukasstockner97, maiself, nirved, dingto
Subscribers: brecht
Differential Revision: https://developer.blender.org/D2586
2017-03-28 20:39:14 +02:00
|
|
|
#include "render/camera.h"
|
|
|
|
#include "render/integrator.h"
|
|
|
|
#include "render/graph.h"
|
|
|
|
#include "render/light.h"
|
|
|
|
#include "render/mesh.h"
|
|
|
|
#include "render/object.h"
|
|
|
|
#include "render/scene.h"
|
|
|
|
#include "render/nodes.h"
|
|
|
|
#include "render/particles.h"
|
|
|
|
#include "render/shader.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
Cycles: Make all #include statements relative to cycles source directory
The idea is to make include statements more explicit and obvious where the
file is coming from, additionally reducing chance of wrong header being
picked up.
For example, it was not obvious whether bvh.h was refferring to builder
or traversal, whenter node.h is a generic graph node or a shader node
and cases like that.
Surely this might look obvious for the active developers, but after some
time of not touching the code it becomes less obvious where file is coming
from.
This was briefly mentioned in T50824 and seems @brecht is fine with such
explicitness, but need to agree with all active developers before committing
this.
Please note that this patch is lacking changes related on GPU/OpenCL
support. This will be solved if/when we all agree this is a good idea to move
forward.
Reviewers: brecht, lukasstockner97, maiself, nirved, dingto, juicyfruit, swerner
Reviewed By: lukasstockner97, maiself, nirved, dingto
Subscribers: brecht
Differential Revision: https://developer.blender.org/D2586
2017-03-28 20:39:14 +02:00
|
|
|
#include "blender/blender_object_cull.h"
|
|
|
|
#include "blender/blender_sync.h"
|
|
|
|
#include "blender/blender_util.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
Cycles: Make all #include statements relative to cycles source directory
The idea is to make include statements more explicit and obvious where the
file is coming from, additionally reducing chance of wrong header being
picked up.
For example, it was not obvious whether bvh.h was refferring to builder
or traversal, whenter node.h is a generic graph node or a shader node
and cases like that.
Surely this might look obvious for the active developers, but after some
time of not touching the code it becomes less obvious where file is coming
from.
This was briefly mentioned in T50824 and seems @brecht is fine with such
explicitness, but need to agree with all active developers before committing
this.
Please note that this patch is lacking changes related on GPU/OpenCL
support. This will be solved if/when we all agree this is a good idea to move
forward.
Reviewers: brecht, lukasstockner97, maiself, nirved, dingto, juicyfruit, swerner
Reviewed By: lukasstockner97, maiself, nirved, dingto
Subscribers: brecht
Differential Revision: https://developer.blender.org/D2586
2017-03-28 20:39:14 +02:00
|
|
|
#include "util/util_foreach.h"
|
|
|
|
#include "util/util_hash.h"
|
|
|
|
#include "util/util_logging.h"
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
/* Utilities */
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
bool BlenderSync::BKE_object_is_modified(BL::Object& b_ob)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
/* test if we can instance or if the object is modified */
|
2014-02-21 15:03:24 +01:00
|
|
|
if(b_ob.type() == BL::Object::type_META) {
|
|
|
|
/* multi-user and dupli metaballs are fused, can't instance */
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if(ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
|
2011-04-27 11:58:34 +00:00
|
|
|
/* modifiers */
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* object level material links */
|
|
|
|
BL::Object::material_slots_iterator slot;
|
2011-08-21 10:32:15 +00:00
|
|
|
for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
|
2011-04-27 11:58:34 +00:00
|
|
|
if(slot->link() == BL::MaterialSlot::link_OBJECT)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
bool BlenderSync::object_is_mesh(BL::Object& b_ob)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
BL::ID b_ob_data = b_ob.data();
|
|
|
|
|
2017-09-29 03:56:14 +02:00
|
|
|
if(!b_ob_data) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(b_ob.type() == BL::Object::type_CURVE) {
|
|
|
|
/* Skip exporting curves without faces, overhead can be
|
|
|
|
* significant if there are many for path animation. */
|
|
|
|
BL::Curve b_curve(b_ob.data());
|
|
|
|
|
|
|
|
return (b_curve.bevel_object() ||
|
|
|
|
b_curve.extrude() != 0.0f ||
|
|
|
|
b_curve.bevel_depth() != 0.0f ||
|
2017-10-03 15:28:57 +05:00
|
|
|
b_curve.dimensions() == BL::Curve::dimensions_2D ||
|
2017-09-29 03:56:14 +02:00
|
|
|
b_ob.modifiers.length());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return (b_ob_data.is_a(&RNA_Mesh) ||
|
|
|
|
b_ob_data.is_a(&RNA_Curve) ||
|
|
|
|
b_ob_data.is_a(&RNA_MetaBall));
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
bool BlenderSync::object_is_light(BL::Object& b_ob)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
BL::ID b_ob_data = b_ob.data();
|
|
|
|
|
|
|
|
return (b_ob_data && b_ob_data.is_a(&RNA_Lamp));
|
|
|
|
}
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
static uint object_ray_visibility(BL::Object& b_ob)
|
2011-09-01 15:53:36 +00:00
|
|
|
{
|
|
|
|
PointerRNA cvisibility = RNA_pointer_get(&b_ob.ptr, "cycles_visibility");
|
|
|
|
uint flag = 0;
|
|
|
|
|
|
|
|
flag |= get_boolean(cvisibility, "camera")? PATH_RAY_CAMERA: 0;
|
|
|
|
flag |= get_boolean(cvisibility, "diffuse")? PATH_RAY_DIFFUSE: 0;
|
|
|
|
flag |= get_boolean(cvisibility, "glossy")? PATH_RAY_GLOSSY: 0;
|
|
|
|
flag |= get_boolean(cvisibility, "transmission")? PATH_RAY_TRANSMIT: 0;
|
|
|
|
flag |= get_boolean(cvisibility, "shadow")? PATH_RAY_SHADOW: 0;
|
2014-09-05 16:17:24 +02:00
|
|
|
flag |= get_boolean(cvisibility, "scatter")? PATH_RAY_VOLUME_SCATTER: 0;
|
2011-09-01 15:53:36 +00:00
|
|
|
|
|
|
|
return flag;
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* Light */
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
void BlenderSync::sync_light(BL::Object& b_parent,
|
|
|
|
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
|
|
|
|
BL::Object& b_ob,
|
2017-06-06 16:27:02 +02:00
|
|
|
BL::Object& b_ob_instance,
|
2017-11-15 07:11:01 -02:00
|
|
|
int random_id,
|
2016-01-30 14:18:29 +01:00
|
|
|
Transform& tfm,
|
|
|
|
bool *use_portal)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
/* test if we need to sync */
|
|
|
|
Light *light;
|
2017-06-06 16:27:02 +02:00
|
|
|
ObjectKey key(b_parent, persistent_id, b_ob_instance);
|
2011-04-27 11:58:34 +00:00
|
|
|
|
Cycles: Added support for light portals
This patch adds support for light portals: objects that help sampling the
environment light, therefore improving convergence. Using them tor other
lights in a unidirectional pathtracer is virtually useless.
The sampling is done with the area-preserving code already used for area lamps.
MIS is used both for combination of different portals and for combining portal-
and envmap-sampling.
The direction of portals is considered, they aren't used if the sampling point
is behind them.
Reviewers: sergey, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: Lapineige, nutel, jtheninja, dsisco11, januz, vitorbalbio, candreacchio, TARDISMaker, lichtwerk, ace_dragon, marcog, mib2berlin, Tunge, lopataasdf, lordodin, sergey, dingto
Differential Revision: https://developer.blender.org/D1133
2015-04-28 00:51:55 +05:00
|
|
|
if(!light_map.sync(&light, b_ob, b_parent, key)) {
|
|
|
|
if(light->is_portal)
|
|
|
|
*use_portal = true;
|
2011-04-27 11:58:34 +00:00
|
|
|
return;
|
Cycles: Added support for light portals
This patch adds support for light portals: objects that help sampling the
environment light, therefore improving convergence. Using them tor other
lights in a unidirectional pathtracer is virtually useless.
The sampling is done with the area-preserving code already used for area lamps.
MIS is used both for combination of different portals and for combining portal-
and envmap-sampling.
The direction of portals is considered, they aren't used if the sampling point
is behind them.
Reviewers: sergey, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: Lapineige, nutel, jtheninja, dsisco11, januz, vitorbalbio, candreacchio, TARDISMaker, lichtwerk, ace_dragon, marcog, mib2berlin, Tunge, lopataasdf, lordodin, sergey, dingto
Differential Revision: https://developer.blender.org/D1133
2015-04-28 00:51:55 +05:00
|
|
|
}
|
2011-09-27 20:37:24 +00:00
|
|
|
|
|
|
|
BL::Lamp b_lamp(b_ob.data());
|
|
|
|
|
|
|
|
/* type */
|
|
|
|
switch(b_lamp.type()) {
|
|
|
|
case BL::Lamp::type_POINT: {
|
|
|
|
BL::PointLamp b_point_lamp(b_lamp);
|
|
|
|
light->size = b_point_lamp.shadow_soft_size();
|
|
|
|
light->type = LIGHT_POINT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BL::Lamp::type_SPOT: {
|
|
|
|
BL::SpotLamp b_spot_lamp(b_lamp);
|
|
|
|
light->size = b_spot_lamp.shadow_soft_size();
|
2012-06-04 17:17:10 +00:00
|
|
|
light->type = LIGHT_SPOT;
|
|
|
|
light->spot_angle = b_spot_lamp.spot_size();
|
|
|
|
light->spot_smooth = b_spot_lamp.spot_blend();
|
2011-09-27 20:37:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BL::Lamp::type_HEMI: {
|
|
|
|
light->type = LIGHT_DISTANT;
|
|
|
|
light->size = 0.0f;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BL::Lamp::type_SUN: {
|
|
|
|
BL::SunLamp b_sun_lamp(b_lamp);
|
|
|
|
light->size = b_sun_lamp.shadow_soft_size();
|
|
|
|
light->type = LIGHT_DISTANT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BL::Lamp::type_AREA: {
|
|
|
|
BL::AreaLamp b_area_lamp(b_lamp);
|
|
|
|
light->size = 1.0f;
|
2013-01-09 21:09:20 +00:00
|
|
|
light->axisu = transform_get_column(&tfm, 0);
|
|
|
|
light->axisv = transform_get_column(&tfm, 1);
|
2011-09-27 20:37:24 +00:00
|
|
|
light->sizeu = b_area_lamp.size();
|
Cycles/Eevee: Implement disk and ellipse shapes for area lamps
The implementation is pretty straightforward.
In Cycles, sampling the shapes is currently done w.r.t. area instead of solid angle.
There is a paper on solid angle sampling for disks [1], but the described algorithm is based on
simply sampling the enclosing square and rejecting samples outside of the disk, which is not exactly
great for Cycles' RNG (we'd need to setup a LCG for the repeated sampling) and for GPU divergence.
Even worse, the algorithm is only defined for disks. For ellipses, the basic idea still works, but a
way to analytically calculate the solid angle is required. This is technically possible [2], but the
calculation is extremely complex and still requires a lookup table for the Heuman Lambda function.
Therefore, I've decided to not implement that for now, we could still look into it later on.
In Eevee, the code uses the existing ltc_evaluate_disk to implement the lighting calculations.
[1]: "Solid Angle Sampling of Disk and Cylinder Lights"
[2]: "Analytical solution for the solid angle subtended at any point by an ellipse via a point source radiation vector potential"
Reviewers: sergey, brecht, fclem
Differential Revision: https://developer.blender.org/D3171
2018-05-24 03:50:16 +02:00
|
|
|
switch(b_area_lamp.shape()) {
|
|
|
|
case BL::AreaLamp::shape_SQUARE:
|
|
|
|
light->sizev = light->sizeu;
|
|
|
|
light->round = false;
|
|
|
|
break;
|
|
|
|
case BL::AreaLamp::shape_RECTANGLE:
|
|
|
|
light->sizev = b_area_lamp.size_y();
|
|
|
|
light->round = false;
|
|
|
|
break;
|
|
|
|
case BL::AreaLamp::shape_DISK:
|
|
|
|
light->sizev = light->sizeu;
|
|
|
|
light->round = true;
|
|
|
|
break;
|
|
|
|
case BL::AreaLamp::shape_ELLIPSE:
|
|
|
|
light->sizev = b_area_lamp.size_y();
|
|
|
|
light->round = true;
|
|
|
|
break;
|
|
|
|
}
|
2011-09-27 20:37:24 +00:00
|
|
|
light->type = LIGHT_AREA;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2011-10-15 23:49:01 +00:00
|
|
|
/* location and (inverted!) direction */
|
2013-01-09 21:09:20 +00:00
|
|
|
light->co = transform_get_column(&tfm, 3);
|
|
|
|
light->dir = -transform_get_column(&tfm, 2);
|
2016-10-29 18:54:42 +02:00
|
|
|
light->tfm = tfm;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
/* shader */
|
2016-05-14 14:50:03 +02:00
|
|
|
vector<Shader*> used_shaders;
|
2011-12-09 00:24:48 +00:00
|
|
|
find_shader(b_lamp, used_shaders, scene->default_light);
|
2011-04-27 11:58:34 +00:00
|
|
|
light->shader = used_shaders[0];
|
|
|
|
|
2011-09-27 20:37:24 +00:00
|
|
|
/* shadow */
|
2017-08-20 23:46:05 +02:00
|
|
|
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
2011-10-15 23:49:01 +00:00
|
|
|
PointerRNA clamp = RNA_pointer_get(&b_lamp.ptr, "cycles");
|
|
|
|
light->cast_shadow = get_boolean(clamp, "cast_shadow");
|
2013-01-30 15:57:15 +00:00
|
|
|
light->use_mis = get_boolean(clamp, "use_multiple_importance_sampling");
|
2013-07-19 22:51:48 +00:00
|
|
|
|
2017-08-20 23:46:05 +02:00
|
|
|
int samples = get_int(clamp, "samples");
|
|
|
|
if(get_boolean(cscene, "use_square_samples"))
|
|
|
|
light->samples = samples * samples;
|
|
|
|
else
|
|
|
|
light->samples = samples;
|
2011-09-27 20:37:24 +00:00
|
|
|
|
2014-11-05 22:48:45 +01:00
|
|
|
light->max_bounces = get_int(clamp, "max_bounces");
|
|
|
|
|
2017-11-15 07:11:01 -02:00
|
|
|
if(b_ob != b_ob_instance) {
|
|
|
|
light->random_id = random_id;
|
2017-11-05 21:59:17 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0);
|
|
|
|
}
|
|
|
|
|
Cycles: Added support for light portals
This patch adds support for light portals: objects that help sampling the
environment light, therefore improving convergence. Using them tor other
lights in a unidirectional pathtracer is virtually useless.
The sampling is done with the area-preserving code already used for area lamps.
MIS is used both for combination of different portals and for combining portal-
and envmap-sampling.
The direction of portals is considered, they aren't used if the sampling point
is behind them.
Reviewers: sergey, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: Lapineige, nutel, jtheninja, dsisco11, januz, vitorbalbio, candreacchio, TARDISMaker, lichtwerk, ace_dragon, marcog, mib2berlin, Tunge, lopataasdf, lordodin, sergey, dingto
Differential Revision: https://developer.blender.org/D1133
2015-04-28 00:51:55 +05:00
|
|
|
if(light->type == LIGHT_AREA)
|
|
|
|
light->is_portal = get_boolean(clamp, "is_portal");
|
|
|
|
else
|
|
|
|
light->is_portal = false;
|
|
|
|
|
|
|
|
if(light->is_portal)
|
|
|
|
*use_portal = true;
|
|
|
|
|
2013-06-07 18:59:23 +00:00
|
|
|
/* visibility */
|
|
|
|
uint visibility = object_ray_visibility(b_ob);
|
|
|
|
light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0;
|
|
|
|
light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0;
|
|
|
|
light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0;
|
2014-09-05 16:17:24 +02:00
|
|
|
light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0;
|
2013-06-07 18:59:23 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* tag */
|
|
|
|
light->tag_update(scene);
|
|
|
|
}
|
|
|
|
|
Cycles: Added support for light portals
This patch adds support for light portals: objects that help sampling the
environment light, therefore improving convergence. Using them tor other
lights in a unidirectional pathtracer is virtually useless.
The sampling is done with the area-preserving code already used for area lamps.
MIS is used both for combination of different portals and for combining portal-
and envmap-sampling.
The direction of portals is considered, they aren't used if the sampling point
is behind them.
Reviewers: sergey, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: Lapineige, nutel, jtheninja, dsisco11, januz, vitorbalbio, candreacchio, TARDISMaker, lichtwerk, ace_dragon, marcog, mib2berlin, Tunge, lopataasdf, lordodin, sergey, dingto
Differential Revision: https://developer.blender.org/D1133
2015-04-28 00:51:55 +05:00
|
|
|
void BlenderSync::sync_background_light(bool use_portal)
|
2012-01-20 17:49:17 +00:00
|
|
|
{
|
|
|
|
BL::World b_world = b_scene.world();
|
|
|
|
|
2012-01-22 13:56:39 +00:00
|
|
|
if(b_world) {
|
2017-08-20 23:46:05 +02:00
|
|
|
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
2012-01-22 13:56:39 +00:00
|
|
|
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
|
2018-06-14 16:18:34 +02:00
|
|
|
|
|
|
|
enum SamplingMethod {
|
|
|
|
SAMPLING_NONE = 0,
|
|
|
|
SAMPLING_AUTOMATIC,
|
|
|
|
SAMPLING_MANUAL,
|
|
|
|
SAMPLING_NUM
|
|
|
|
};
|
|
|
|
int sampling_method = get_enum(cworld, "sampling_method", SAMPLING_NUM, SAMPLING_AUTOMATIC);
|
|
|
|
bool sample_as_light = (sampling_method != SAMPLING_NONE);
|
2012-01-22 13:56:39 +00:00
|
|
|
|
Cycles: Added support for light portals
This patch adds support for light portals: objects that help sampling the
environment light, therefore improving convergence. Using them tor other
lights in a unidirectional pathtracer is virtually useless.
The sampling is done with the area-preserving code already used for area lamps.
MIS is used both for combination of different portals and for combining portal-
and envmap-sampling.
The direction of portals is considered, they aren't used if the sampling point
is behind them.
Reviewers: sergey, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: Lapineige, nutel, jtheninja, dsisco11, januz, vitorbalbio, candreacchio, TARDISMaker, lichtwerk, ace_dragon, marcog, mib2berlin, Tunge, lopataasdf, lordodin, sergey, dingto
Differential Revision: https://developer.blender.org/D1133
2015-04-28 00:51:55 +05:00
|
|
|
if(sample_as_light || use_portal) {
|
2012-01-22 13:56:39 +00:00
|
|
|
/* test if we need to sync */
|
|
|
|
Light *light;
|
|
|
|
ObjectKey key(b_world, 0, b_world);
|
|
|
|
|
|
|
|
if(light_map.sync(&light, b_world, b_world, key) ||
|
2016-02-03 15:00:55 +01:00
|
|
|
world_recalc ||
|
|
|
|
b_world.ptr.data != world_map)
|
2012-01-22 13:56:39 +00:00
|
|
|
{
|
|
|
|
light->type = LIGHT_BACKGROUND;
|
2018-06-14 16:18:34 +02:00
|
|
|
if(sampling_method == SAMPLING_MANUAL) {
|
|
|
|
light->map_resolution = get_int(cworld, "sample_map_resolution");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
light->map_resolution = 0;
|
|
|
|
}
|
2012-01-22 13:56:39 +00:00
|
|
|
light->shader = scene->default_background;
|
Cycles: Added support for light portals
This patch adds support for light portals: objects that help sampling the
environment light, therefore improving convergence. Using them tor other
lights in a unidirectional pathtracer is virtually useless.
The sampling is done with the area-preserving code already used for area lamps.
MIS is used both for combination of different portals and for combining portal-
and envmap-sampling.
The direction of portals is considered, they aren't used if the sampling point
is behind them.
Reviewers: sergey, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: Lapineige, nutel, jtheninja, dsisco11, januz, vitorbalbio, candreacchio, TARDISMaker, lichtwerk, ace_dragon, marcog, mib2berlin, Tunge, lopataasdf, lordodin, sergey, dingto
Differential Revision: https://developer.blender.org/D1133
2015-04-28 00:51:55 +05:00
|
|
|
light->use_mis = sample_as_light;
|
2015-07-12 17:56:54 +02:00
|
|
|
light->max_bounces = get_int(cworld, "max_bounces");
|
Cycles: Added support for light portals
This patch adds support for light portals: objects that help sampling the
environment light, therefore improving convergence. Using them tor other
lights in a unidirectional pathtracer is virtually useless.
The sampling is done with the area-preserving code already used for area lamps.
MIS is used both for combination of different portals and for combining portal-
and envmap-sampling.
The direction of portals is considered, they aren't used if the sampling point
is behind them.
Reviewers: sergey, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: Lapineige, nutel, jtheninja, dsisco11, januz, vitorbalbio, candreacchio, TARDISMaker, lichtwerk, ace_dragon, marcog, mib2berlin, Tunge, lopataasdf, lordodin, sergey, dingto
Differential Revision: https://developer.blender.org/D1133
2015-04-28 00:51:55 +05:00
|
|
|
|
2017-08-20 23:46:05 +02:00
|
|
|
int samples = get_int(cworld, "samples");
|
|
|
|
if(get_boolean(cscene, "use_square_samples"))
|
|
|
|
light->samples = samples * samples;
|
|
|
|
else
|
|
|
|
light->samples = samples;
|
2012-01-22 13:56:39 +00:00
|
|
|
|
|
|
|
light->tag_update(scene);
|
|
|
|
light_map.set_recalc(b_world);
|
|
|
|
}
|
2012-01-20 17:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
world_map = b_world.ptr.data;
|
|
|
|
world_recalc = false;
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* Object */
|
|
|
|
|
2018-02-26 16:46:48 +01:00
|
|
|
Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
|
2018-05-30 15:21:21 +02:00
|
|
|
BL::DepsgraphObjectInstance& b_instance,
|
2015-04-10 18:09:58 +05:00
|
|
|
uint layer_flag,
|
|
|
|
float motion_time,
|
|
|
|
bool hide_tris,
|
2016-11-13 00:45:16 +01:00
|
|
|
BlenderObjectCulling& culling,
|
2015-04-10 18:09:58 +05:00
|
|
|
bool *use_portal)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2018-05-30 15:21:21 +02:00
|
|
|
const bool is_instance = b_instance.is_instance();
|
|
|
|
BL::Object b_ob = b_instance.object();
|
|
|
|
BL::Object b_parent = is_instance ? b_instance.parent()
|
|
|
|
: b_instance.object();
|
|
|
|
BL::Object b_ob_instance = is_instance ? b_instance.instance_object()
|
2017-06-06 16:27:02 +02:00
|
|
|
: b_ob;
|
2017-06-06 13:58:40 +02:00
|
|
|
const bool motion = motion_time != 0.0f;
|
|
|
|
/*const*/ Transform tfm = get_transform(b_ob.matrix_world());
|
|
|
|
int *persistent_id = NULL;
|
|
|
|
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
|
2017-06-06 16:27:02 +02:00
|
|
|
if(is_instance) {
|
2018-05-30 15:21:21 +02:00
|
|
|
persistent_id_array = b_instance.persistent_id();
|
2017-06-06 13:58:40 +02:00
|
|
|
persistent_id = persistent_id_array.data;
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* light is handled separately */
|
|
|
|
if(object_is_light(b_ob)) {
|
2013-06-13 13:09:32 +00:00
|
|
|
/* don't use lamps for excluded layers used as mask layer */
|
2017-11-22 10:52:39 -02:00
|
|
|
if(!motion && !((layer_flag & view_layer.holdout_layer) &&
|
|
|
|
(layer_flag & view_layer.exclude_layer)))
|
2017-06-06 16:27:02 +02:00
|
|
|
{
|
|
|
|
sync_light(b_parent,
|
|
|
|
persistent_id,
|
|
|
|
b_ob,
|
|
|
|
b_ob_instance,
|
2018-05-30 15:21:21 +02:00
|
|
|
is_instance ? b_instance.random_id() : 0,
|
2017-06-06 16:27:02 +02:00
|
|
|
tfm,
|
|
|
|
use_portal);
|
|
|
|
}
|
2012-11-08 16:35:28 +00:00
|
|
|
|
|
|
|
return NULL;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* only interested in object that we can create meshes from */
|
2016-11-13 00:45:16 +01:00
|
|
|
if(!object_is_mesh(b_ob)) {
|
2012-11-08 16:35:28 +00:00
|
|
|
return NULL;
|
2016-11-13 00:45:16 +01:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2016-11-13 00:16:50 +01:00
|
|
|
/* Perform object culling. */
|
2016-11-13 00:45:16 +01:00
|
|
|
if(culling.test(scene, b_ob, tfm)) {
|
2015-04-10 18:09:58 +05:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-09-29 03:56:14 +02:00
|
|
|
/* Visibility flags for both parent and child. */
|
2017-11-18 06:06:27 +01:00
|
|
|
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
|
|
|
|
bool use_holdout = (layer_flag & view_layer.holdout_layer) != 0 ||
|
|
|
|
get_boolean(cobject, "is_holdout");
|
2017-09-29 03:56:14 +02:00
|
|
|
uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
|
|
|
|
|
|
|
|
if(b_parent.ptr.data != b_ob.ptr.data) {
|
|
|
|
visibility &= object_ray_visibility(b_parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make holdout objects on excluded layer invisible for non-camera rays. */
|
2017-11-22 10:52:39 -02:00
|
|
|
if(use_holdout && (layer_flag & view_layer.exclude_layer)) {
|
2017-09-29 03:56:14 +02:00
|
|
|
visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Hide objects not on render layer from camera rays. */
|
2017-11-22 10:52:39 -02:00
|
|
|
if(!(layer_flag & view_layer.layer)) {
|
2017-09-29 03:56:14 +02:00
|
|
|
visibility &= ~PATH_RAY_CAMERA;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Don't export completely invisible objects. */
|
|
|
|
if(visibility == 0) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-04-30 12:49:26 +00:00
|
|
|
/* key to lookup object */
|
2017-06-06 16:27:02 +02:00
|
|
|
ObjectKey key(b_parent, persistent_id, b_ob_instance);
|
2011-04-27 11:58:34 +00:00
|
|
|
Object *object;
|
2012-04-30 12:49:26 +00:00
|
|
|
|
|
|
|
/* motion vector case */
|
|
|
|
if(motion) {
|
|
|
|
object = object_map.find(key);
|
|
|
|
|
2018-03-08 04:04:52 +01:00
|
|
|
if(object && object->use_motion()) {
|
|
|
|
/* Set transform at matching motion time step. */
|
|
|
|
int time_index = object->motion_step(motion_time);
|
|
|
|
if(time_index >= 0) {
|
|
|
|
object->motion[time_index] = tfm;
|
2016-08-07 22:41:35 +03:00
|
|
|
}
|
|
|
|
|
2014-03-29 13:03:46 +01:00
|
|
|
/* mesh deformation */
|
|
|
|
if(object->mesh)
|
2018-02-26 16:46:48 +01:00
|
|
|
sync_mesh_motion(b_depsgraph, b_ob, object, motion_time);
|
2012-04-30 12:49:26 +00:00
|
|
|
}
|
|
|
|
|
2012-11-08 16:35:28 +00:00
|
|
|
return object;
|
2012-04-30 12:49:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* test if we need to sync */
|
2011-04-27 11:58:34 +00:00
|
|
|
bool object_updated = false;
|
|
|
|
|
2011-11-12 14:29:52 +00:00
|
|
|
if(object_map.sync(&object, b_ob, b_parent, key))
|
|
|
|
object_updated = true;
|
|
|
|
|
|
|
|
/* mesh sync */
|
2018-02-26 16:46:48 +01:00
|
|
|
object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, hide_tris);
|
2012-05-02 09:33:45 +00:00
|
|
|
|
2013-11-26 20:34:29 +01:00
|
|
|
/* special case not tracked by object update flags */
|
|
|
|
|
|
|
|
/* holdout */
|
2012-05-02 09:33:45 +00:00
|
|
|
if(use_holdout != object->use_holdout) {
|
|
|
|
object->use_holdout = use_holdout;
|
|
|
|
scene->object_manager->tag_update(scene);
|
2012-11-09 23:28:51 +00:00
|
|
|
object_updated = true;
|
2012-05-02 09:33:45 +00:00
|
|
|
}
|
2011-11-12 14:29:52 +00:00
|
|
|
|
2013-11-26 20:34:29 +01:00
|
|
|
if(visibility != object->visibility) {
|
|
|
|
object->visibility = visibility;
|
|
|
|
object_updated = true;
|
|
|
|
}
|
|
|
|
|
2017-02-09 14:19:01 +01:00
|
|
|
bool is_shadow_catcher = get_boolean(cobject, "is_shadow_catcher");
|
|
|
|
if(is_shadow_catcher != object->is_shadow_catcher) {
|
|
|
|
object->is_shadow_catcher = is_shadow_catcher;
|
|
|
|
object_updated = true;
|
|
|
|
}
|
|
|
|
|
2012-11-08 16:35:28 +00:00
|
|
|
/* object sync
|
|
|
|
* transform comparison should not be needed, but duplis don't work perfect
|
2012-09-03 13:18:23 +00:00
|
|
|
* in the depsgraph and may not signal changes, so this is a workaround */
|
|
|
|
if(object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) {
|
2011-10-03 17:42:24 +00:00
|
|
|
object->name = b_ob.name().c_str();
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
object->pass_id = b_ob.pass_index();
|
2011-04-27 11:58:34 +00:00
|
|
|
object->tfm = tfm;
|
2018-03-08 04:04:52 +01:00
|
|
|
object->motion.clear();
|
2011-12-21 20:51:43 +00:00
|
|
|
|
2014-03-29 13:03:46 +01:00
|
|
|
/* motion blur */
|
2018-03-08 04:04:52 +01:00
|
|
|
Scene::MotionType need_motion = scene->need_motion();
|
|
|
|
if(need_motion != Scene::MOTION_NONE && object->mesh) {
|
2014-03-29 13:03:46 +01:00
|
|
|
Mesh *mesh = object->mesh;
|
2014-03-29 13:03:47 +01:00
|
|
|
mesh->use_motion_blur = false;
|
2018-03-08 04:04:52 +01:00
|
|
|
mesh->motion_steps = 0;
|
|
|
|
|
|
|
|
uint motion_steps;
|
2014-03-29 13:03:47 +01:00
|
|
|
|
2018-03-08 04:04:52 +01:00
|
|
|
if(scene->need_motion() == Scene::MOTION_BLUR) {
|
|
|
|
motion_steps = object_motion_steps(b_parent, b_ob);
|
2018-03-12 17:33:46 +01:00
|
|
|
if(motion_steps && object_use_deform_motion(b_parent, b_ob)) {
|
2018-03-08 04:04:52 +01:00
|
|
|
mesh->motion_steps = motion_steps;
|
2014-03-29 13:03:47 +01:00
|
|
|
mesh->use_motion_blur = true;
|
|
|
|
}
|
2018-03-08 04:04:52 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
motion_steps = 3;
|
|
|
|
mesh->motion_steps = motion_steps;
|
|
|
|
}
|
2014-03-29 13:03:46 +01:00
|
|
|
|
2018-07-01 16:31:46 +02:00
|
|
|
object->motion.clear();
|
2018-03-08 04:04:52 +01:00
|
|
|
object->motion.resize(motion_steps, transform_empty());
|
2014-03-29 13:03:46 +01:00
|
|
|
|
2018-03-12 17:33:46 +01:00
|
|
|
if(motion_steps) {
|
|
|
|
object->motion[motion_steps/2] = tfm;
|
|
|
|
|
|
|
|
for(size_t step = 0; step < motion_steps; step++) {
|
|
|
|
motion_times.insert(object->motion_time(step));
|
|
|
|
}
|
2014-03-29 13:03:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-14 18:13:44 +03:00
|
|
|
/* dupli texture coordinates and random_id */
|
2017-06-06 16:27:02 +02:00
|
|
|
if(is_instance) {
|
2018-05-30 15:21:21 +02:00
|
|
|
object->dupli_generated = 0.5f*get_float3(b_instance.orco()) - make_float3(0.5f, 0.5f, 0.5f);
|
|
|
|
object->dupli_uv = get_float2(b_instance.uv());
|
|
|
|
object->random_id = b_instance.random_id();
|
2018-04-04 13:16:56 +02:00
|
|
|
|
|
|
|
/* Sync possible particle data. */
|
2018-05-30 15:21:21 +02:00
|
|
|
sync_dupli_particle(b_ob, b_instance, object);
|
2012-10-04 21:40:39 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
object->dupli_uv = make_float2(0.0f, 0.0f);
|
2017-04-14 18:13:44 +03:00
|
|
|
object->random_id = hash_int_2d(hash_string(object->name.c_str()), 0);
|
2012-10-04 21:40:39 +00:00
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
object->tag_update(scene);
|
|
|
|
}
|
2012-11-08 16:35:28 +00:00
|
|
|
|
|
|
|
return object;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
static bool object_render_hide_original(BL::Object::type_enum ob_type,
|
|
|
|
BL::Object::dupli_type_enum dupli_type)
|
2012-12-09 12:43:40 +00:00
|
|
|
{
|
2013-06-13 14:33:18 +00:00
|
|
|
/* metaball exception, they duplicate self */
|
|
|
|
if(ob_type == BL::Object::type_META)
|
|
|
|
return false;
|
|
|
|
|
2012-12-09 12:43:40 +00:00
|
|
|
return (dupli_type == BL::Object::dupli_type_VERTS ||
|
|
|
|
dupli_type == BL::Object::dupli_type_FACES ||
|
|
|
|
dupli_type == BL::Object::dupli_type_FRAMES);
|
|
|
|
}
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
static bool object_render_hide(BL::Object& b_ob,
|
|
|
|
bool top_level,
|
|
|
|
bool parent_hide,
|
2018-06-06 16:43:37 +02:00
|
|
|
bool& hide_triangles,
|
|
|
|
BL::Depsgraph::mode_enum depsgraph_mode)
|
2013-03-01 14:55:30 +00:00
|
|
|
{
|
|
|
|
/* check if we should render or hide particle emitter */
|
|
|
|
BL::Object::particle_systems_iterator b_psys;
|
|
|
|
|
|
|
|
bool hair_present = false;
|
2017-12-21 13:29:14 -02:00
|
|
|
bool has_particles = false;
|
2013-03-01 14:55:30 +00:00
|
|
|
bool show_emitter = false;
|
2013-11-27 17:14:53 +01:00
|
|
|
bool hide_emitter = false;
|
2013-08-07 19:02:15 +00:00
|
|
|
bool hide_as_dupli_parent = false;
|
|
|
|
bool hide_as_dupli_child_original = false;
|
2013-03-01 14:55:30 +00:00
|
|
|
|
|
|
|
for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) {
|
|
|
|
if((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) &&
|
|
|
|
(b_psys->settings().type()==BL::ParticleSettings::type_HAIR))
|
|
|
|
hair_present = true;
|
2017-12-21 13:29:14 -02:00
|
|
|
has_particles = true;
|
2013-03-01 14:55:30 +00:00
|
|
|
}
|
|
|
|
|
2018-06-06 16:43:37 +02:00
|
|
|
/* Both mode_PREVIEW and mode_VIEWPORT are treated the same here.*/
|
|
|
|
const bool show_duplicator = depsgraph_mode == BL::Depsgraph::mode_RENDER
|
|
|
|
? b_ob.show_duplicator_for_render()
|
|
|
|
: b_ob.show_duplicator_for_viewport();
|
|
|
|
|
2017-12-21 13:29:14 -02:00
|
|
|
if(has_particles) {
|
2018-06-06 16:43:37 +02:00
|
|
|
show_emitter = show_duplicator;
|
2017-12-21 13:29:14 -02:00
|
|
|
hide_emitter = !show_emitter;
|
|
|
|
} else if(b_ob.is_duplicator()) {
|
2018-06-06 16:43:37 +02:00
|
|
|
if(top_level || show_duplicator) {
|
2013-08-07 19:02:15 +00:00
|
|
|
hide_as_dupli_parent = true;
|
2017-12-21 13:29:14 -02:00
|
|
|
}
|
|
|
|
}
|
2013-03-01 14:55:30 +00:00
|
|
|
|
|
|
|
/* hide original object for duplis */
|
|
|
|
BL::Object parent = b_ob.parent();
|
2014-12-26 13:34:48 +05:00
|
|
|
while(parent) {
|
|
|
|
if(object_render_hide_original(b_ob.type(),
|
|
|
|
parent.dupli_type()))
|
|
|
|
{
|
|
|
|
if(parent_hide) {
|
|
|
|
hide_as_dupli_child_original = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
parent = parent.parent();
|
|
|
|
}
|
2013-08-07 19:02:15 +00:00
|
|
|
|
2013-12-09 21:57:30 +01:00
|
|
|
hide_triangles = hide_emitter;
|
|
|
|
|
2013-08-07 19:02:15 +00:00
|
|
|
if(show_emitter) {
|
2013-08-12 06:53:17 +00:00
|
|
|
return false;
|
2013-08-07 19:02:15 +00:00
|
|
|
}
|
|
|
|
else if(hair_present) {
|
2013-12-09 21:57:30 +01:00
|
|
|
return hide_as_dupli_child_original;
|
2013-08-07 19:02:15 +00:00
|
|
|
}
|
|
|
|
else {
|
2013-12-09 21:57:30 +01:00
|
|
|
return (hide_as_dupli_parent || hide_as_dupli_child_original);
|
2013-08-07 19:02:15 +00:00
|
|
|
}
|
2013-03-01 14:55:30 +00:00
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* Object Loop */
|
|
|
|
|
2018-02-26 16:46:48 +01:00
|
|
|
void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
/* layer data */
|
2014-03-29 13:03:46 +01:00
|
|
|
bool motion = motion_time != 0.0f;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2012-04-30 12:49:26 +00:00
|
|
|
if(!motion) {
|
|
|
|
/* prepare for sync */
|
|
|
|
light_map.pre_sync();
|
|
|
|
mesh_map.pre_sync();
|
|
|
|
object_map.pre_sync();
|
2012-10-18 15:00:32 +00:00
|
|
|
particle_system_map.pre_sync();
|
2014-03-29 13:03:46 +01:00
|
|
|
motion_times.clear();
|
2012-04-30 12:49:26 +00:00
|
|
|
}
|
2013-10-17 16:05:57 +00:00
|
|
|
else {
|
|
|
|
mesh_motion_synced.clear();
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2016-11-13 00:45:16 +01:00
|
|
|
/* initialize culling */
|
|
|
|
BlenderObjectCulling culling(scene, b_scene);
|
2015-04-10 18:09:58 +05:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* object loop */
|
2012-09-04 13:29:07 +00:00
|
|
|
bool cancel = false;
|
Cycles: Added support for light portals
This patch adds support for light portals: objects that help sampling the
environment light, therefore improving convergence. Using them tor other
lights in a unidirectional pathtracer is virtually useless.
The sampling is done with the area-preserving code already used for area lamps.
MIS is used both for combination of different portals and for combining portal-
and envmap-sampling.
The direction of portals is considered, they aren't used if the sampling point
is behind them.
Reviewers: sergey, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: Lapineige, nutel, jtheninja, dsisco11, januz, vitorbalbio, candreacchio, TARDISMaker, lichtwerk, ace_dragon, marcog, mib2berlin, Tunge, lopataasdf, lordodin, sergey, dingto
Differential Revision: https://developer.blender.org/D1133
2015-04-28 00:51:55 +05:00
|
|
|
bool use_portal = false;
|
2012-09-04 13:29:07 +00:00
|
|
|
|
2018-06-06 16:43:37 +02:00
|
|
|
BL::Depsgraph::mode_enum depsgraph_mode = b_depsgraph.mode();
|
|
|
|
|
2018-05-30 15:21:21 +02:00
|
|
|
BL::Depsgraph::object_instances_iterator b_instance_iter;
|
|
|
|
for(b_depsgraph.object_instances.begin(b_instance_iter);
|
|
|
|
b_instance_iter != b_depsgraph.object_instances.end() && !cancel;
|
|
|
|
++b_instance_iter)
|
2017-06-06 13:58:40 +02:00
|
|
|
{
|
2018-05-30 15:21:21 +02:00
|
|
|
BL::DepsgraphObjectInstance b_instance = *b_instance_iter;
|
|
|
|
BL::Object b_ob = b_instance.object();
|
2017-09-21 12:55:14 +02:00
|
|
|
|
2017-04-25 16:18:24 +02:00
|
|
|
progress.set_sync_status("Synchronizing object", b_ob.name());
|
|
|
|
|
|
|
|
/* load per-object culling data */
|
|
|
|
culling.init_object(scene, b_ob);
|
|
|
|
|
|
|
|
/* test if object needs to be hidden */
|
|
|
|
bool hide_tris;
|
|
|
|
|
2018-06-06 16:43:37 +02:00
|
|
|
if(!object_render_hide(b_ob, true, true, hide_tris, depsgraph_mode)) {
|
2017-04-25 16:18:24 +02:00
|
|
|
/* object itself */
|
2018-02-26 16:46:48 +01:00
|
|
|
sync_object(b_depsgraph,
|
2018-05-30 15:21:21 +02:00
|
|
|
b_instance,
|
2017-04-25 16:18:24 +02:00
|
|
|
~(0), /* until we get rid of layers */
|
|
|
|
motion_time,
|
|
|
|
hide_tris,
|
|
|
|
culling,
|
|
|
|
&use_portal);
|
|
|
|
}
|
|
|
|
|
|
|
|
cancel = progress.get_cancel();
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
2012-09-28 12:37:20 +00:00
|
|
|
progress.set_sync_status("");
|
|
|
|
|
2012-09-04 13:29:07 +00:00
|
|
|
if(!cancel && !motion) {
|
Cycles: Added support for light portals
This patch adds support for light portals: objects that help sampling the
environment light, therefore improving convergence. Using them tor other
lights in a unidirectional pathtracer is virtually useless.
The sampling is done with the area-preserving code already used for area lamps.
MIS is used both for combination of different portals and for combining portal-
and envmap-sampling.
The direction of portals is considered, they aren't used if the sampling point
is behind them.
Reviewers: sergey, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: Lapineige, nutel, jtheninja, dsisco11, januz, vitorbalbio, candreacchio, TARDISMaker, lichtwerk, ace_dragon, marcog, mib2berlin, Tunge, lopataasdf, lordodin, sergey, dingto
Differential Revision: https://developer.blender.org/D1133
2015-04-28 00:51:55 +05:00
|
|
|
sync_background_light(use_portal);
|
2012-04-30 12:49:26 +00:00
|
|
|
|
|
|
|
/* handle removed data and modified pointers */
|
|
|
|
if(light_map.post_sync())
|
|
|
|
scene->light_manager->tag_update(scene);
|
|
|
|
if(mesh_map.post_sync())
|
|
|
|
scene->mesh_manager->tag_update(scene);
|
|
|
|
if(object_map.post_sync())
|
|
|
|
scene->object_manager->tag_update(scene);
|
2012-10-18 15:00:32 +00:00
|
|
|
if(particle_system_map.post_sync())
|
|
|
|
scene->particle_system_manager->tag_update(scene);
|
2012-04-30 12:49:26 +00:00
|
|
|
}
|
2013-10-17 16:05:57 +00:00
|
|
|
|
|
|
|
if(motion)
|
|
|
|
mesh_motion_synced.clear();
|
2012-04-30 12:49:26 +00:00
|
|
|
}
|
|
|
|
|
2016-01-30 14:18:29 +01:00
|
|
|
void BlenderSync::sync_motion(BL::RenderSettings& b_render,
|
2018-02-26 16:46:48 +01:00
|
|
|
BL::Depsgraph& b_depsgraph,
|
2016-01-30 14:18:29 +01:00
|
|
|
BL::Object& b_override,
|
2015-07-21 15:36:35 +02:00
|
|
|
int width, int height,
|
|
|
|
void **python_thread_state)
|
2012-04-30 12:49:26 +00:00
|
|
|
{
|
|
|
|
if(scene->need_motion() == Scene::MOTION_NONE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* get camera object here to deal with camera switch */
|
|
|
|
BL::Object b_cam = b_scene.camera();
|
|
|
|
if(b_override)
|
|
|
|
b_cam = b_override;
|
|
|
|
|
2012-10-15 21:12:58 +00:00
|
|
|
Camera prevcam = *(scene->camera);
|
2012-04-30 12:49:26 +00:00
|
|
|
|
2014-03-29 13:03:46 +01:00
|
|
|
int frame_center = b_scene.frame_current();
|
2016-09-14 14:58:55 +02:00
|
|
|
float subframe_center = b_scene.frame_subframe();
|
2015-06-29 17:40:13 +02:00
|
|
|
float frame_center_delta = 0.0f;
|
|
|
|
|
|
|
|
if(scene->need_motion() != Scene::MOTION_PASS &&
|
|
|
|
scene->camera->motion_position != Camera::MOTION_POSITION_CENTER)
|
|
|
|
{
|
|
|
|
float shuttertime = scene->camera->shuttertime;
|
|
|
|
if(scene->camera->motion_position == Camera::MOTION_POSITION_END) {
|
|
|
|
frame_center_delta = -shuttertime * 0.5f;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
assert(scene->camera->motion_position == Camera::MOTION_POSITION_START);
|
|
|
|
frame_center_delta = shuttertime * 0.5f;
|
|
|
|
}
|
2018-02-26 16:46:48 +01:00
|
|
|
|
2016-09-14 14:58:55 +02:00
|
|
|
float time = frame_center + subframe_center + frame_center_delta;
|
2015-06-29 17:40:13 +02:00
|
|
|
int frame = (int)floorf(time);
|
|
|
|
float subframe = time - frame;
|
|
|
|
python_thread_state_restore(python_thread_state);
|
|
|
|
b_engine.frame_set(frame, subframe);
|
|
|
|
python_thread_state_save(python_thread_state);
|
|
|
|
sync_camera_motion(b_render, b_cam, width, height, 0.0f);
|
2018-02-26 16:46:48 +01:00
|
|
|
sync_objects(b_depsgraph, 0.0f);
|
2015-06-29 17:40:13 +02:00
|
|
|
}
|
2014-03-29 13:03:46 +01:00
|
|
|
|
|
|
|
/* always sample these times for camera motion */
|
|
|
|
motion_times.insert(-1.0f);
|
|
|
|
motion_times.insert(1.0f);
|
|
|
|
|
|
|
|
/* note iteration over motion_times set happens in sorted order */
|
|
|
|
foreach(float relative_time, motion_times) {
|
2018-03-10 00:37:07 +01:00
|
|
|
/* center time is already handled. */
|
|
|
|
if(relative_time == 0.0f) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-07-21 15:36:35 +02:00
|
|
|
VLOG(1) << "Synchronizing motion for the relative time "
|
|
|
|
<< relative_time << ".";
|
|
|
|
|
2014-03-29 13:03:46 +01:00
|
|
|
/* fixed shutter time to get previous and next frame for motion pass */
|
2016-07-16 18:56:59 +02:00
|
|
|
float shuttertime = scene->motion_shutter_time();
|
2014-03-29 13:03:46 +01:00
|
|
|
|
|
|
|
/* compute frame and subframe time */
|
2016-09-14 14:58:55 +02:00
|
|
|
float time = frame_center + subframe_center + frame_center_delta + relative_time * shuttertime * 0.5f;
|
2014-03-29 13:03:46 +01:00
|
|
|
int frame = (int)floorf(time);
|
|
|
|
float subframe = time - frame;
|
|
|
|
|
|
|
|
/* change frame */
|
2014-02-12 23:13:45 +01:00
|
|
|
python_thread_state_restore(python_thread_state);
|
2014-05-21 15:47:11 +02:00
|
|
|
b_engine.frame_set(frame, subframe);
|
2014-02-12 23:13:45 +01:00
|
|
|
python_thread_state_save(python_thread_state);
|
2012-04-30 12:49:26 +00:00
|
|
|
|
2014-03-31 13:36:51 +02:00
|
|
|
/* sync camera, only supports two times at the moment */
|
2015-07-21 15:36:35 +02:00
|
|
|
if(relative_time == -1.0f || relative_time == 1.0f) {
|
|
|
|
sync_camera_motion(b_render,
|
|
|
|
b_cam,
|
|
|
|
width, height,
|
|
|
|
relative_time);
|
|
|
|
}
|
2014-03-31 13:36:51 +02:00
|
|
|
|
2014-03-29 13:03:46 +01:00
|
|
|
/* sync object */
|
2018-02-26 16:46:48 +01:00
|
|
|
sync_objects(b_depsgraph, relative_time);
|
2012-04-30 12:49:26 +00:00
|
|
|
}
|
2012-01-20 17:49:17 +00:00
|
|
|
|
2014-02-12 21:49:34 +01:00
|
|
|
/* we need to set the python thread state again because this
|
|
|
|
* function assumes it is being executed from python and will
|
|
|
|
* try to save the thread state */
|
2014-02-12 23:13:45 +01:00
|
|
|
python_thread_state_restore(python_thread_state);
|
2016-09-14 14:58:55 +02:00
|
|
|
b_engine.frame_set(frame_center, subframe_center);
|
2014-02-12 23:13:45 +01:00
|
|
|
python_thread_state_save(python_thread_state);
|
2012-10-15 21:12:58 +00:00
|
|
|
|
|
|
|
/* tag camera for motion update */
|
|
|
|
if(scene->camera->motion_modified(prevcam))
|
|
|
|
scene->camera->tag_update();
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CCL_NAMESPACE_END
|
|
|
|
|