41 BL::BlendData &b_data,
45 bool use_developer_ui,
52 procedural_map(scene),
55 particle_system_map(scene),
61 use_developer_ui(use_developer_ui),
68 dicing_rate = preview ?
RNA_float_get(&cscene,
"preview_dicing_rate") :
70 max_subdivisions =
RNA_int_get(&cscene,
"max_subdivisions");
81 this->b_data = b_data;
82 this->b_scene = b_scene;
100 bool dicing_prop_changed =
false;
102 float updated_dicing_rate = preview ?
RNA_float_get(&cscene,
"preview_dicing_rate") :
105 if (dicing_rate != updated_dicing_rate) {
106 dicing_rate = updated_dicing_rate;
107 dicing_prop_changed =
true;
110 int updated_max_subdivisions =
RNA_int_get(&cscene,
"max_subdivisions");
112 if (max_subdivisions != updated_max_subdivisions) {
113 max_subdivisions = updated_max_subdivisions;
114 dicing_prop_changed =
true;
117 if (dicing_prop_changed) {
120 for (
const pair<const GeometryKey, Geometry *> &iter : geometry_map.
key_to_scene_data()) {
123 Mesh *mesh =
static_cast<Mesh *
>(geom);
134 for (BL::DepsgraphUpdate &b_update : b_depsgraph.updates) {
141 BL::ID b_id(b_update.id());
144 if (b_id.is_a(&RNA_Material)) {
145 BL::Material b_mat(b_id);
149 else if (b_id.is_a(&RNA_Light)) {
150 BL::Light b_light(b_id);
154 else if (b_id.is_a(&RNA_Object)) {
155 BL::Object b_ob(b_id);
156 const bool can_have_geometry = object_can_have_geometry(b_ob);
157 const bool is_light = !can_have_geometry && object_is_light(b_ob);
159 if (b_ob.is_instancer() && b_update.is_updated_shading()) {
164 if (can_have_geometry ||
is_light) {
165 const bool updated_geometry = b_update.is_updated_geometry();
168 if (can_have_geometry) {
169 if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
173 if (updated_geometry ||
176 BL::ID key = BKE_object_is_modified(b_ob) ? b_ob : b_ob.data();
180 map<void *, set<BL::ID>>::const_iterator instance_geometries =
181 instance_geometries_by_object.find(b_ob.ptr.data);
182 if (instance_geometries != instance_geometries_by_object.end()) {
183 for (BL::ID geometry : instance_geometries->second) {
189 if (updated_geometry) {
190 BL::Object::particle_systems_iterator b_psys;
191 for (b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end();
200 if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
205 if (updated_geometry) {
210 else if (object_is_camera(b_ob)) {
215 else if (b_id.is_a(&RNA_Mesh)) {
216 BL::Mesh b_mesh(b_id);
220 else if (b_id.is_a(&RNA_World)) {
221 BL::World b_world(b_id);
222 if (world_map == b_world.ptr.data) {
228 else if (b_id.is_a(&RNA_Scene)) {
232 else if (b_id.is_a(&RNA_Volume)) {
233 BL::Volume b_volume(b_id);
246 has_updates_ |= viewport_parameters.
modified(new_viewport_parameters);
251 BL::Depsgraph &b_depsgraph,
252 BL::SpaceView3D &b_v3d,
253 BL::Object &b_override,
256 void **python_thread_state,
261 const int frame = b_scene.frame_current();
264 if (!has_updates_ && !auto_refresh_update) {
270 BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
274 const bool background = !b_v3d;
278 sync_film(b_view_layer, b_v3d);
279 sync_shaders(b_depsgraph, b_v3d, auto_refresh_update);
282 geometry_synced.clear();
287 sync_objects(b_depsgraph, b_v3d);
289 sync_motion(b_render, b_depsgraph, b_v3d, b_override, width, height, python_thread_state);
291 geometry_synced.clear();
297 VLOG_INFO <<
"Total time spent synchronizing data: " <<
timer.get_time();
299 has_updates_ =
false;
310 experimental = (
get_enum(cscene,
"feature_set") != 0);
314 integrator->set_min_bounce(
get_int(cscene,
"min_light_bounces"));
315 integrator->set_max_bounce(
get_int(cscene,
"max_bounces"));
317 integrator->set_max_diffuse_bounce(
get_int(cscene,
"diffuse_bounces"));
318 integrator->set_max_glossy_bounce(
get_int(cscene,
"glossy_bounces"));
319 integrator->set_max_transmission_bounce(
get_int(cscene,
"transmission_bounces"));
320 integrator->set_max_volume_bounce(
get_int(cscene,
"volume_bounces"));
322 integrator->set_transparent_min_bounce(
get_int(cscene,
"min_transparent_bounces"));
323 integrator->set_transparent_max_bounce(
get_int(cscene,
"transparent_max_bounces"));
325 integrator->set_volume_max_steps(
get_int(cscene,
"volume_max_steps"));
326 float volume_step_rate = (preview) ?
get_float(cscene,
"volume_preview_step_rate") :
328 integrator->set_volume_step_rate(volume_step_rate);
330 integrator->set_caustics_reflective(
get_boolean(cscene,
"caustics_reflective"));
331 integrator->set_caustics_refractive(
get_boolean(cscene,
"caustics_refractive"));
332 integrator->set_filter_glossy(
get_float(cscene,
"blur_glossy"));
337 if (b_scene.frame_subframe() != 0.0f) {
341 seed +=
hash_uint2((
int)(b_scene.frame_subframe() * (
float)INT_MAX),
346 integrator->set_seed(
seed);
348 integrator->set_sample_clamp_direct(
get_float(cscene,
"sample_clamp_direct"));
349 integrator->set_sample_clamp_indirect(
get_float(cscene,
"sample_clamp_indirect"));
351 integrator->set_motion_blur(view_layer.use_motion_blur);
354 bool use_light_tree =
get_boolean(cscene,
"use_light_tree");
355 integrator->set_use_light_tree(use_light_tree);
356 integrator->set_light_sampling_threshold(
get_float(cscene,
"light_sampling_threshold"));
358 if (integrator->use_light_tree_is_modified()) {
365 switch (sampling_pattern) {
383 if (!use_developer_ui) {
389 const bool is_vertex_baking = scene->bake_manager->get_baking() &&
390 b_scene.render().bake().target() !=
391 BL::BakeSettings::target_IMAGE_TEXTURES;
392 scene->bake_manager->set_use_seed(is_vertex_baking);
393 if (is_vertex_baking) {
399 integrator->set_sampling_pattern(sampling_pattern);
402 bool use_adaptive_sampling =
false;
404 samples =
get_int(cscene,
"preview_samples");
405 use_adaptive_sampling =
RNA_boolean_get(&cscene,
"use_preview_adaptive_sampling");
406 integrator->set_use_adaptive_sampling(use_adaptive_sampling);
407 integrator->set_adaptive_threshold(
get_float(cscene,
"preview_adaptive_threshold"));
408 integrator->set_adaptive_min_samples(
get_int(cscene,
"preview_adaptive_min_samples"));
411 samples =
get_int(cscene,
"samples");
412 use_adaptive_sampling =
RNA_boolean_get(&cscene,
"use_adaptive_sampling");
413 integrator->set_use_adaptive_sampling(use_adaptive_sampling);
414 integrator->set_adaptive_threshold(
get_float(cscene,
"adaptive_threshold"));
415 integrator->set_adaptive_min_samples(
get_int(cscene,
"adaptive_min_samples"));
418 float scrambling_distance =
get_float(cscene,
"scrambling_distance");
419 bool auto_scrambling_distance =
get_boolean(cscene,
"auto_scrambling_distance");
420 if (auto_scrambling_distance) {
429 if (use_adaptive_sampling) {
435 scrambling_distance *= 4.0f /
sqrtf(samples);
439 bool preview_scrambling_distance =
get_boolean(cscene,
"preview_scrambling_distance");
440 if ((preview && !preview_scrambling_distance) ||
443 scrambling_distance = 1.0f;
446 if (scrambling_distance != 1.0f) {
447 VLOG_INFO <<
"Using scrambling distance: " << scrambling_distance;
449 integrator->set_scrambling_distance(scrambling_distance);
453 integrator->set_ao_bounces(
get_int(cscene,
"ao_bounces"));
456 integrator->set_ao_bounces(
get_int(cscene,
"ao_bounces_render"));
460 integrator->set_ao_bounces(0);
463#ifdef WITH_CYCLES_DEBUG
466 integrator->set_direct_light_sampling_type(direct_light_sampling_type);
469 integrator->set_use_guiding(
get_boolean(cscene,
"use_guiding"));
470 integrator->set_use_surface_guiding(
get_boolean(cscene,
"use_surface_guiding"));
471 integrator->set_use_volume_guiding(
get_boolean(cscene,
"use_volume_guiding"));
472 integrator->set_guiding_training_samples(
get_int(cscene,
"guiding_training_samples"));
474 if (use_developer_ui) {
475 integrator->set_deterministic_guiding(
get_boolean(cscene,
"use_deterministic_guiding"));
476 integrator->set_surface_guiding_probability(
get_float(cscene,
"surface_guiding_probability"));
477 integrator->set_volume_guiding_probability(
get_float(cscene,
"volume_guiding_probability"));
478 integrator->set_use_guiding_direct_light(
get_boolean(cscene,
"use_guiding_direct_light"));
479 integrator->set_use_guiding_mis_weights(
get_boolean(cscene,
"use_guiding_mis_weights"));
482 integrator->set_guiding_distribution_type(guiding_distribution_type);
485 "guiding_directional_sampling_type",
488 integrator->set_guiding_directional_sampling_type(guiding_directional_sampling_type);
489 integrator->set_guiding_roughness_threshold(
get_float(cscene,
"guiding_roughness_threshold"));
493 b_scene, b_view_layer, background, denoise_device_info);
497 if (is_vertex_baking) {
498 denoise_params.
use =
false;
501 integrator->set_use_denoise(denoise_params.
use);
506 if (denoise_params.
use) {
507 integrator->set_denoiser_type(denoise_params.
type);
508 integrator->set_denoise_use_gpu(denoise_params.
use_gpu);
509 integrator->set_denoise_start_sample(denoise_params.
start_sample);
510 integrator->set_use_denoise_pass_albedo(denoise_params.
use_pass_albedo);
511 integrator->set_use_denoise_pass_normal(denoise_params.
use_pass_normal);
512 integrator->set_denoiser_prefilter(denoise_params.
prefilter);
513 integrator->set_denoiser_quality(denoise_params.
quality);
523void BlenderSync::sync_film(BL::ViewLayer &b_view_layer, BL::SpaceView3D &b_v3d)
528 Film *film = scene->film;
532 film->set_display_pass(new_viewport_parameters.display_pass);
533 film->set_show_active_pixels(new_viewport_parameters.show_active_pixels);
536 film->set_exposure(
get_float(cscene,
"film_exposure"));
537 film->set_filter_type(
539 float filter_width = (film->get_filter_type() ==
FILTER_BOX) ? 1.0f :
541 film->set_filter_width(filter_width);
543 if (b_scene.world()) {
544 BL::WorldMistSettings b_mist = b_scene.world().mist_settings();
546 film->set_mist_start(b_mist.start());
547 film->set_mist_depth(b_mist.depth());
549 switch (b_mist.falloff()) {
550 case BL::WorldMistSettings::falloff_QUADRATIC:
551 film->set_mist_falloff(2.0f);
553 case BL::WorldMistSettings::falloff_LINEAR:
554 film->set_mist_falloff(1.0f);
556 case BL::WorldMistSettings::falloff_INVERSE_QUADRATIC:
557 film->set_mist_falloff(0.5f);
565 film->set_use_approximate_shadow_catcher(
true);
568 film->set_use_approximate_shadow_catcher(!
get_boolean(crl,
"use_pass_shadow_catcher"));
576 view_layer.name = b_view_layer.name();
579 view_layer.use_background_shader = b_view_layer.use_sky();
581 view_layer.use_surfaces = b_view_layer.use_solid() || scene->bake_manager->get_baking();
582 view_layer.use_hair = b_view_layer.use_strand();
583 view_layer.use_volumes = b_view_layer.use_volumes();
584 view_layer.use_motion_blur = b_view_layer.use_motion_blur() &&
585 b_scene.render().use_motion_blur();
588 view_layer.material_override = b_view_layer.material_override();
590 view_layer.world_override = b_view_layer.world_override();
594 int use_layer_samples =
get_enum(cscene,
"use_layer_samples");
596 view_layer.bound_samples = (use_layer_samples == 1);
597 view_layer.samples = 0;
599 if (use_layer_samples != 2) {
600 int samples = b_view_layer.samples();
601 view_layer.samples = samples;
606void BlenderSync::sync_images()
610 const bool is_interface_locked = b_engine.render() && b_engine.render().use_lock_interface();
618 for (BL::Image &b_image : b_data.images) {
620 if (is_builtin ==
false) {
621 b_image.buffers_free();
631 string name = b_pass.name();
632#define MAP_PASS(passname, passtype, noisy) \
633 if (name == passname) { \
635 mode = (noisy) ? PassMode::NOISY : PassMode::DENOISED; \
706 Pass *pass = scene->create_node<
Pass>();
708 pass->set_type(type);
709 pass->set_name(ustring(name));
710 pass->set_mode(mode);
718 set<Pass *> clear_passes(scene->passes.begin(), scene->passes.end());
719 scene->delete_nodes(clear_passes);
726 int crypto_depth =
divide_up(
min(16, b_view_layer.pass_cryptomatte_depth()), 2);
727 scene->film->set_cryptomatte_depth(crypto_depth);
729 if (b_view_layer.use_pass_cryptomatte_object()) {
732 if (b_view_layer.use_pass_cryptomatte_material()) {
735 if (b_view_layer.use_pass_cryptomatte_asset()) {
738 scene->film->set_cryptomatte_passes(cryptomatte_passes);
740 unordered_set<string> expected_passes;
743 BL::ViewLayer::aovs_iterator b_aov_iter;
744 for (b_view_layer.aovs.begin(b_aov_iter); b_aov_iter != b_view_layer.aovs.end(); ++b_aov_iter) {
745 BL::AOV b_aov(*b_aov_iter);
746 if (!b_aov.is_valid()) {
750 string name = b_aov.name();
753 pass_add(scene, type, name.c_str());
754 expected_passes.insert(name);
758 BL::ViewLayer::lightgroups_iterator b_lightgroup_iter;
759 for (b_view_layer.lightgroups.begin(b_lightgroup_iter);
760 b_lightgroup_iter != b_view_layer.lightgroups.end();
763 BL::Lightgroup b_lightgroup(*b_lightgroup_iter);
765 string name =
string_printf(
"Combined_%s", b_lightgroup.name().c_str());
768 pass->set_lightgroup(ustring(b_lightgroup.name()));
769 expected_passes.insert(name);
773 for (BL::RenderPass &b_pass : b_rlay.passes) {
778 if (!expected_passes.count(b_pass.name())) {
779 LOG(ERROR) <<
"Unknown pass " << b_pass.name();
785 (b_view_layer.use_motion_blur() && b_scene.render().use_motion_blur()))
790 pass_add(scene, pass_type, b_pass.name().c_str(), pass_mode);
793 scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold());
803 const bool is_interface_locked = b_engine.render() && b_engine.render().use_lock_interface();
804 const bool is_persistent_data = b_engine.render() && b_engine.render().use_persistent_data();
805 const bool can_free_caches =
810 !scene->bake_manager->get_baking() &&
814 if (!can_free_caches) {
820 for (BL::Object &b_ob : b_depsgraph.objects) {
823 if (b_ob.type() == BL::Object::type_GREASEPENCIL || b_ob.type() == BL::Object::type_GPENCIL) {
826 b_ob.cache_release();
833 const bool background,
834 const bool use_developer_ui)
840 if (shadingsystem == 0) {
843 else if (shadingsystem == 1) {
847 if (background || (use_developer_ui &&
get_enum(cscene,
"debug_bvh_type"))) {
866 texture_limit =
RNA_enum_get(&cscene,
"texture_limit_render");
871 if (texture_limit > 0 && b_scene.render().use_simplify()) {
872 params.texture_limit = 1 << (texture_limit + 6);
880 params.background = background;
894 BL::Preferences &b_preferences,
901 if (background && !b_engine.is_preview()) {
906 params.temp_dir = b_engine.temporary_directory();
914 params.background = background;
919 b_preferences, b_scene,
params.background, b_engine.is_preview(),
params.denoise_device);
922 int samples =
get_int(cscene,
"samples");
923 int preview_samples =
get_int(cscene,
"preview_samples");
924 int sample_offset =
get_int(cscene,
"sample_offset");
928 params.sample_offset = sample_offset;
931 params.samples = preview_samples;
932 if (
params.samples == 0) {
945 params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
954 if (shadingsystem == 0) {
957 else if (shadingsystem == 1) {
974 params.use_profiling =
params.device.has_profiling && !b_engine.is_preview() && background &&
982 params.use_auto_tile =
false;
989 BL::ViewLayer &b_view_layer,
994 DENOISER_INPUT_RGB = 1,
995 DENOISER_INPUT_RGB_ALBEDO = 2,
996 DENOISER_INPUT_RGB_ALBEDO_NORMAL = 3,
1004 int input_passes = -1;
1016 input_passes = (DenoiserInput)
get_enum(
1017 cscene,
"denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO_NORMAL);
1022 denoising.
use =
false;
1038 input_passes = (DenoiserInput)
get_enum(
1039 cscene,
"preview_denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO);
1045 denoising.
use =
false;
1050 switch (input_passes) {
1051 case DENOISER_INPUT_RGB:
1056 case DENOISER_INPUT_RGB_ALBEDO:
1061 case DENOISER_INPUT_RGB_ALBEDO_NORMAL:
1067 LOG(ERROR) <<
"Unhandled input passes enum " << input_passes;
typedef double(DMatrix)[4][4]
DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, bool background, bool preview, DeviceInfo &preferences_device)
int blender_device_threads(BL::Scene &b_scene)
static unsigned long seed
static bool print_render_stats
BlenderSync(BL::RenderEngine &b_engine, BL::BlendData &b_data, BL::Scene &b_scene, Scene *scene, bool preview, bool use_developer_ui, Progress &progress)
static DenoiseParams get_denoise_params(BL::Scene &b_scene, BL::ViewLayer &b_view_layer, bool background, const DeviceInfo &denoise_device)
static bool get_session_pause(BL::Scene &b_scene, bool background)
void sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d)
void sync_data(BL::RenderSettings &b_render, BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, BL::Object &b_override, int width, int height, void **python_thread_state, const DeviceInfo &denoise_device_info)
void sync_render_passes(BL::RenderLayer &b_render_layer, BL::ViewLayer &b_view_layer)
void sync_view_layer(BL::ViewLayer &b_view_layer)
void sync_integrator(BL::ViewLayer &b_view_layer, bool background, const DeviceInfo &denoise_device_info)
void free_data_after_sync(BL::Depsgraph &b_depsgraph)
static SceneParams get_scene_params(BL::Scene &b_scene, const bool background, const bool use_developer_ui)
void reset(BL::BlendData &b_data, BL::Scene &b_scene)
static SessionParams get_session_params(BL::RenderEngine &b_engine, BL::Preferences &b_userpref, BL::Scene &b_scene, bool background)
bool shader_modified(const BlenderViewportParameters &other) const
bool modified(const BlenderViewportParameters &other) const
DenoiserPrefilter prefilter
static DenoiserType automatic_viewport_denoiser_type(const DeviceInfo &denoise_device_info)
bool set_animation_frame_update(int frame)
void tag_update(Scene *scene, uint32_t flag)
AdaptiveSampling get_adaptive_sampling() const
static const int MAX_SAMPLES
void set_recalc(const BL::ID &id)
void post_sync(bool do_delete=true)
const map< K, T * > & key_to_scene_data()
static bool image_is_builtin(BL::Image &ima, BL::RenderEngine &engine)
static float get_float(PointerRNA &ptr, const char *name)
static bool get_boolean(PointerRNA &ptr, const char *name)
static int get_int(PointerRNA &ptr, const char *name)
static int get_enum(PointerRNA &ptr, const char *name, int num_values=-1, int default_value=-1)
static Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob, bool preview, bool experimental)
DebugFlags & DebugFlags()
@ DENOISER_QUALITY_BALANCED
@ DENOISER_PREFILTER_FAST
@ DENOISER_PREFILTER_NONE
#define CCL_NAMESPACE_END
ccl_device_inline uint hash_uint2(uint kx, uint ky)
@ DIRECT_LIGHT_SAMPLING_MIS
@ DIRECT_LIGHT_SAMPLING_NUM
GuidingDirectionalSamplingType
@ GUIDING_DIRECTIONAL_SAMPLING_NUM_TYPES
@ GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS
@ SAMPLING_PATTERN_AUTOMATIC
@ SAMPLING_PATTERN_BLUE_NOISE_FIRST
@ SAMPLING_PATTERN_TABULATED_SOBOL
@ SAMPLING_PATTERN_BLUE_NOISE_PURE
@ PASS_TRANSMISSION_DIRECT
@ PASS_TRANSMISSION_COLOR
@ PASS_TRANSMISSION_INDIRECT
@ PASS_GUIDING_PROBABILITY
@ PASS_ADAPTIVE_AUX_BUFFER
@ PASS_GUIDING_AVG_ROUGHNESS
@ GUIDING_TYPE_PARALLAX_AWARE_VMM
bool is_builtin(const void *, const StringRef attribute_id)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
int RNA_int_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_id_pointer_create(ID *id)
bool string_startswith(const string_view s, const string_view start)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
static bool get_known_pass_type(BL::RenderPass &b_pass, PassType &type, PassMode &mode)
#define MAP_PASS(passname, passtype, noisy)
static Pass * pass_add(Scene *scene, PassType type, const char *name, PassMode mode=PassMode::DENOISED)
static CCL_NAMESPACE_BEGIN const char * cryptomatte_prefix
ccl_device_inline bool is_light(const ccl_global KernelLightTreeEmitter *kemitter)
ccl_device_inline int clamp(int a, int mn, int mx)
ccl_device_inline size_t divide_up(size_t x, size_t y)