77 SOCKET_NODE(geometry,
"Geometry", Geometry::get_node_base_type());
85 SOCKET_BOOLEAN(hide_on_missing_motion,
"Hide on Missing Motion",
false);
89 SOCKET_FLOAT(shadow_terminator_shading_offset,
"Shadow Terminator Shading Offset", 0.0f);
90 SOCKET_FLOAT(shadow_terminator_geometry_offset,
"Shadow Terminator Geometry Offset", 0.1f);
96 SOCKET_BOOLEAN(is_caustics_receiver,
"Receive Shadow Caustics",
false);
98 SOCKET_NODE(particle_system,
"Particle System", ParticleSystem::get_node_type());
104 SOCKET_UINT(receiver_light_set,
"Light Set Index", 0);
106 SOCKET_UINT(blocker_shadow_set,
"Shadow Set Index", 0);
114 particle_system =
NULL;
129 bool have_motion =
false;
131 for (
size_t i = 0; i < motion.size(); i++) {
133 if (hide_on_missing_motion) {
149 have_motion = have_motion || motion[i] != tfm;
160 BoundBox mbounds = geometry->bounds;
171 for (
float t = 0.0f; t < 1.0f; t += (1.0f / 128.0f)) {
180 if (geometry->transform_applied) {
195 geometry->apply_transform(tfm, apply_to_motion);
200 geometry->transform_negative_scaled =
true;
204 geometry->compute_bounds();
219 if (use_holdout_is_modified()) {
223 if (is_shadow_catcher_is_modified()) {
224 scene->tag_shadow_catcher_modified();
230 if (tfm_is_modified() || motion_is_modified()) {
234 if (visibility_is_modified()) {
238 foreach (
Node *node, geometry->get_used_shaders()) {
246 scene->camera->need_flags_update =
true;
247 scene->object_manager->tag_update(scene,
flag);
252 return (motion.size() > 1);
257 return (
use_motion()) ? 2.0f * step / (motion.size() - 1) - 1.0f : 0.0f;
263 for (
size_t step = 0; step < motion.size(); step++) {
294 Mesh *mesh =
static_cast<Mesh *
>(geometry);
296 if (!mesh->has_volume) {
303 foreach (
Node *node, mesh->get_used_shaders()) {
305 if (shader->has_volume) {
306 if ((shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) ||
307 (shader->has_volume_attribute_dependency))
309 step_rate =
fminf(shader->get_volume_step_rate(), step_rate);
324 foreach (
Attribute &attr, volume->attributes.attributes) {
333 float voxel_step_size = volume->get_step_size();
335 if (voxel_step_size == 0.0f) {
354 else if (volume->get_object_space()) {
360 if (voxel_step_size > 0.0f) {
361 step_size =
fminf(voxel_step_size, step_size);
373 step_size *= step_rate;
394 if (!(get_visibility() &
404 foreach (
Node *node, geom->get_used_shaders()) {
415 if (get_receiver_light_set()) {
428 if (get_blocker_shadow_set()) {
453 if (
static_cast<Volume *
>(geom)->get_object_space()) {
478 float pass_id = ob->pass_id;
479 float random_number = (
float)ob->random_id * (1.0f / (
float)0xFFFFFFFF);
481 ob->particle_index +
state->particle_offset[ob->particle_system] :
487 kobject.
color[0] = color.x;
488 kobject.
color[1] = color.y;
489 kobject.
color[2] = color.z;
490 kobject.
alpha = ob->alpha;
498 ob->receiver_light_set;
502 ob->blocker_shadow_set;
505 if (geom->get_use_motion_blur()) {
506 state->have_motion =
true;
515 Mesh *mesh =
static_cast<Mesh *
>(geom);
536 tfm_pre = ob->motion[0];
537 tfm_post = ob->motion[ob->motion.size() - 1];
548 tfm_pre = tfm_pre * itfm;
549 tfm_post = tfm_post * itfm;
553 object_motion_pass[motion_pass_offset + 0] = tfm_pre;
554 object_motion_pass[motion_pass_offset + 1] = tfm_post;
561 if (ob->tfm_is_modified() || ob->motion_is_modified() || update_all) {
567 state->have_motion =
true;
575 kobject.
dupli_uv[0] = ob->dupli_uv[0];
576 kobject.
dupli_uv[1] = ob->dupli_uv[1];
577 int totalsteps = geom->get_motion_steps();
578 kobject.
numsteps = (totalsteps - 1) / 2;
581 static_cast<Mesh *
>(geom)->get_verts().size() :
583 static_cast<Hair *
>(geom)->get_curve_keys().size() :
590 if (ob->asset_name_is_modified() || update_all) {
598 (1.0f - 0.5f * ob->shadow_terminator_shading_offset);
605 if (ob->is_caustics_caster) {
608 if (ob->is_caustics_receiver) {
613 if (ob->use_holdout) {
621 state->have_curves =
true;
624 state->have_points =
true;
627 state->have_volumes =
true;
631 auto it = scene->lightgroups.find(ob->
lightgroup);
632 if (it != scene->lightgroups.end()) {
642 if (!scene->integrator->get_use_light_tree()) {
655 foreach (
Object *ob, scene->objects) {
657 if (
Geometry *
const geom = ob->geometry) {
659 prim_offset = ((
Hair *
const)geom)->curve_segment_offset;
662 prim_offset = geom->prim_offset;
666 object_prim_offset[obj_index] = prim_offset;
677 state.have_motion =
false;
678 state.have_curves =
false;
679 state.have_points =
false;
680 state.have_volumes =
false;
682 state.queue_start_object = 0;
692 scene->objects.size());
696 uint *motion_offsets =
state.motion_offset.resize(scene->objects.size());
697 uint motion_offset = 0;
699 foreach (
Object *ob, scene->objects) {
700 *motion_offsets = motion_offset;
705 motion_offset += ob->motion.size();
714 int numparticles = 1;
716 state.particle_offset[psys] = numparticles;
725 static const int OBJECTS_PER_TASK = 32;
726 parallel_for(blocked_range<size_t>(0, scene->objects.size(), OBJECTS_PER_TASK),
727 [&](
const blocked_range<size_t> &r) {
728 for (size_t i = r.begin(); i != r.end(); i++) {
729 Object *ob = state.scene->objects[i];
730 device_update_object_transform(&state, ob, update_all, scene);
734 if (progress.get_cancel()) {
738 dscene->objects.copy_to_device_if_modified();
740 dscene->object_motion_pass.copy_to_device();
743 dscene->object_motion.copy_to_device();
746 dscene->data.bvh.have_motion =
state.have_motion;
747 dscene->data.bvh.have_curves =
state.have_curves;
748 dscene->data.bvh.have_points =
state.have_points;
749 dscene->data.bvh.have_volumes =
state.have_volumes;
751 dscene->objects.clear_modified();
752 dscene->object_motion_pass.clear_modified();
753 dscene->object_motion.clear_modified();
781 VLOG_INFO <<
"Total " << scene->objects.size() <<
" objects.";
785 if (scene->objects.size() == 0) {
792 if (scene->update_stats) {
793 scene->update_stats->object.times.add_entry({
"device_update (assign index)", time});
798 foreach (
Object *
object, scene->objects) {
799 object->index = index++;
803 if (object->is_modified()) {
816 if (scene->update_stats) {
817 scene->update_stats->object.times.add_entry(
818 {
"device_update (copy objects to device)", time});
822 progress.set_status(
"Updating Objects",
"Copying Transformations to device");
823 device_update_transforms(dscene, scene, progress);
826 if (progress.get_cancel()) {
834 if (scene->update_stats) {
835 scene->update_stats->object.times.add_entry(
836 {
"device_update (apply static transforms)", time});
840 progress.set_status(
"Updating Objects",
"Applying Static Transformations");
841 apply_static_transforms(dscene, scene, progress);
844 foreach (
Object *
object, scene->objects) {
845 object->clear_modified();
857 if (scene->update_stats) {
858 scene->update_stats->object.times.add_entry({
"device_update_flags", time});
868 update_flags = UPDATE_NONE;
869 need_flags_update =
false;
872 if (scene->objects.size() == 0) {
877 uint *object_flag = dscene->object_flag.data();
878 float *object_volume_step = dscene->object_volume_step.data();
882 bool has_volume_objects =
false;
883 foreach (
Object *
object, scene->objects) {
884 if (object->geometry->has_volume) {
889 volume_objects.push_back(
object);
890 object_volume_step[
object->index] =
object->compute_volume_step_size();
893 object_volume_step[
object->index] =
FLT_MAX;
895 has_volume_objects =
true;
898 object_volume_step[
object->index] =
FLT_MAX;
902 foreach (
Object *
object, scene->objects) {
903 if (object->geometry->has_volume) {
905 object_flag[
object->index] &= ~SD_OBJECT_HAS_VOLUME_ATTRIBUTES;
907 foreach (
Attribute &attr, object->geometry->attributes.attributes) {
917 if (object->is_shadow_catcher) {
921 object_flag[
object->index] &= ~SD_OBJECT_SHADOW_CATCHER;
925 object->intersects_volume =
false;
926 foreach (
Object *volume_object, volume_objects) {
927 if (
object == volume_object) {
930 if (object->bounds.intersects(volume_object->
bounds)) {
932 object->intersects_volume =
true;
937 else if (has_volume_objects) {
946 dscene->object_flag.copy_to_device();
947 dscene->object_volume_step.copy_to_device();
949 dscene->object_flag.clear_modified();
950 dscene->object_volume_step.clear_modified();
963 foreach (
Object *
object, scene->objects) {
967 Mesh *mesh =
static_cast<Mesh *
>(geom);
968 if (mesh->patch_table) {
969 uint patch_map_offset = 2 * (mesh->patch_table_offset + mesh->patch_table->total_size() -
980 size_t attr_map_offset =
object->attr_map_offset;
983 if (attr_map_offset == 0) {
1014 map<Geometry *, int> geometry_users;
1020 foreach (
Object *
object, scene->objects) {
1021 map<Geometry *, int>::iterator it = geometry_users.find(object->geometry);
1023 if (it == geometry_users.end()) {
1024 geometry_users[
object->geometry] = 1;
1038 foreach (
Object *
object, scene->objects) {
1049 Mesh *mesh =
static_cast<Mesh *
>(geom);
1060 if (!(motion_blur && object->use_motion())) {
1062 object->apply_transform(apply_to_motion);
1080 update_flags |=
flag;
1100 scene->geometry_manager->tag_update(scene, geometry_flag);
1118 string manifest =
"{";
1120 unordered_set<ustring, ustringHash> objects;
1121 foreach (
Object *
object, scene->objects) {
1122 if (objects.count(object->name)) {
1125 objects.insert(object->name);
1127 manifest +=
string_printf(
"\"%s\":\"%08x\",", object->name.c_str(), hash_name);
1129 manifest[manifest.size() - 1] =
'}';
1135 string manifest =
"{";
1136 unordered_set<ustring, ustringHash> assets;
1137 foreach (
Object *ob, scene->objects) {
1138 if (assets.count(ob->asset_name)) {
1141 assets.insert(ob->asset_name);
1143 manifest +=
string_printf(
"\"%s\":\"%08x\",", ob->asset_name.c_str(), hash_asset);
1145 manifest[manifest.size() - 1] =
'}';
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
ImageHandle & data_voxel()
device_vector< DecomposedTransform > object_motion
device_vector< Transform > object_motion_pass
device_vector< float > object_volume_step
device_vector< uint > object_prim_offset
device_vector< uint > object_flag
device_vector< KernelObject > objects
virtual BVHLayoutMask get_bvh_layout_mask(uint kernel_features) const =0
bool has_true_displacement() const
virtual PrimitiveType primitive_type() const =0
string get_cryptomatte_objects(Scene *scene)
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void tag_update(Scene *scene, uint32_t flag)
void device_update_object_transform(UpdateObjectTransformState *state, Object *ob, bool update_all, const Scene *scene)
void device_free(Device *device, DeviceScene *dscene, bool force_free)
string get_cryptomatte_assets(Scene *scene)
void device_update_geom_offsets(Device *device, DeviceScene *dscene, Scene *scene)
void device_update_prim_offsets(Device *device, DeviceScene *dscene, Scene *scene)
void device_update_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
void apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
void device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress, bool bounds_valid=true)
void tag_update(Scene *scene)
T * alloc(size_t width, size_t height=0, size_t depth=0)
void free_if_need_realloc(bool force_free)
#define CCL_NAMESPACE_END
draw_view in_light_buf[] float
ccl_device_inline uint particle_index(KernelGlobals kg, int particle)
ccl_device_inline float object_volume_density(KernelGlobals kg, int object)
#define LIGHT_LINK_SET_MAX
@ ATTR_STD_VOLUME_VELOCITY
@ ATTR_STD_MOTION_VERTEX_POSITION
@ PATH_RAY_VOLUME_SCATTER
@ PATH_RAY_ALL_VISIBILITY
#define OBJECT_MOTION_PASS_SIZE
@ SD_OBJECT_HAS_VOLUME_ATTRIBUTES
@ SD_OBJECT_INTERSECTS_VOLUME
@ SD_OBJECT_NEGATIVE_SCALE
@ SD_OBJECT_HAS_VOLUME_MOTION
@ SD_OBJECT_CAUSTICS_RECEIVER
@ SD_OBJECT_SHADOW_CATCHER
@ SD_OBJECT_TRANSFORM_APPLIED
@ SD_OBJECT_HAS_VERTEX_MOTION
@ SD_OBJECT_CAUSTICS_CASTER
@ BVH_LAYOUT_MULTI_HIPRT_EMBREE
@ BVH_LAYOUT_MULTI_METAL_EMBREE
#define LIGHT_LINK_MASK_ALL
#define SHADOW_CATCHER_OBJECT_VISIBILITY(is_shadow_catcher, visibility)
CCL_NAMESPACE_BEGIN ccl_device_inline float2 zero_float2()
ccl_device_inline float average(const float2 a)
ccl_device_inline float reduce_min(const float2 a)
ccl_device_inline float2 fabs(const float2 a)
ccl_device_inline float3 one_float3()
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
float util_hash_to_float(uint32_t hash)
uint32_t util_murmur_hash3(const void *key, int len, uint32_t seed)
static void update(bNodeTree *ntree)
#define SOCKET_POINT(name, ui_name, default_value,...)
#define SOCKET_FLOAT(name, ui_name, default_value,...)
#define SOCKET_INT(name, ui_name, default_value,...)
#define SOCKET_NODE(name, ui_name, node_type,...)
#define SOCKET_TRANSFORM(name, ui_name, default_value,...)
#define SOCKET_UINT(name, ui_name, default_value,...)
#define NODE_DEFINE(structname)
#define SOCKET_COLOR(name, ui_name, default_value,...)
#define SOCKET_TRANSFORM_ARRAY(name, ui_name, default_value,...)
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
#define SOCKET_POINT2(name, ui_name, default_value,...)
#define SOCKET_STRING(name, ui_name, default_value,...)
#define SOCKET_UINT64(name, ui_name, default_value,...)
static float object_volume_density(const Transform &tfm, Geometry *geom)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
BoundBox transformed(const Transform *tfm) const
__forceinline bool valid() const
__forceinline float3 size() const
__forceinline void grow(const float3 &pt)
uint64_t shadow_set_membership
float shadow_terminator_geometry_offset
uint attribute_map_offset
uint64_t light_set_membership
float shadow_terminator_shading_offset
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
void compute_bounds(bool motion_blur)
int motion_step(float time) const
NODE_DECLARE BoundBox bounds
bool usable_as_light() const
int get_device_index() const
void apply_transform(bool apply_to_motion)
float compute_volume_step_size() const
bool has_light_linking() const
bool is_traceable() const
uint visibility_for_tracing() const
void tag_update(Scene *scene)
float motion_time(int step) const
bool has_shadow_linking() const
struct LightgroupMembership * lightgroup
size_t num_points() const
vector< Object * > objects
@ IMAGE_DATA_TYPE_NANOVDB_FP16
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT3
@ IMAGE_DATA_TYPE_NANOVDB_FPN