39 BL::BlendData &b_data,
43 bool use_developer_ui,
50 procedural_map(
scene),
53 particle_system_map(
scene),
59 use_developer_ui(use_developer_ui),
66 dicing_rate = preview ?
RNA_float_get(&cscene,
"preview_dicing_rate") :
68 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()) {
135 for (BL::DepsgraphUpdate &b_update : b_depsgraph.updates) {
142 BL::ID b_id(b_update.id());
145 if (b_id.is_a(&RNA_Material)) {
150 else if (b_id.is_a(&RNA_Light)) {
155 else if (b_id.is_a(&RNA_Object)) {
157 const bool can_have_geometry = object_can_have_geometry(b_ob);
158 const bool is_light = !can_have_geometry && object_is_light(b_ob);
160 if (b_ob.is_instancer() && b_update.is_updated_shading()) {
165 if (can_have_geometry || is_light) {
166 const bool updated_geometry = b_update.is_updated_geometry();
169 if (can_have_geometry) {
170 if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
174 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();
199 if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
204 if (updated_geometry) {
211 else if (b_id.is_a(&RNA_Mesh)) {
216 else if (b_id.is_a(&RNA_World)) {
218 if (world_map == b_world.ptr.data) {
223 else if (b_id.is_a(&RNA_Volume)) {
237 has_updates_ |= viewport_parameters.
modified(new_viewport_parameters);
243 BL::SpaceView3D &b_v3d,
247 void **python_thread_state)
251 const int frame = b_scene.frame_current();
254 if (!has_updates_ && !auto_refresh_update) {
264 const bool background = !b_v3d;
268 sync_film(b_view_layer, b_v3d);
269 sync_shaders(b_depsgraph, b_v3d, auto_refresh_update);
272 geometry_synced.clear();
276 sync_objects(b_depsgraph, b_v3d);
278 sync_motion(b_render, b_depsgraph, b_v3d, b_override,
width,
height, python_thread_state);
280 geometry_synced.clear();
286 free_data_after_sync(b_depsgraph);
290 has_updates_ =
false;
299 experimental = (
get_enum(cscene,
"feature_set") != 0);
303 integrator->set_min_bounce(
get_int(cscene,
"min_light_bounces"));
304 integrator->set_max_bounce(
get_int(cscene,
"max_bounces"));
306 integrator->set_max_diffuse_bounce(
get_int(cscene,
"diffuse_bounces"));
307 integrator->set_max_glossy_bounce(
get_int(cscene,
"glossy_bounces"));
308 integrator->set_max_transmission_bounce(
get_int(cscene,
"transmission_bounces"));
309 integrator->set_max_volume_bounce(
get_int(cscene,
"volume_bounces"));
311 integrator->set_transparent_min_bounce(
get_int(cscene,
"min_transparent_bounces"));
312 integrator->set_transparent_max_bounce(
get_int(cscene,
"transparent_max_bounces"));
314 integrator->set_volume_max_steps(
get_int(cscene,
"volume_max_steps"));
315 float volume_step_rate = (preview) ?
get_float(cscene,
"volume_preview_step_rate") :
317 integrator->set_volume_step_rate(volume_step_rate);
319 integrator->set_caustics_reflective(
get_boolean(cscene,
"caustics_reflective"));
320 integrator->set_caustics_refractive(
get_boolean(cscene,
"caustics_refractive"));
321 integrator->set_filter_glossy(
get_float(cscene,
"blur_glossy"));
326 if (b_scene.frame_subframe() != 0.0f) {
330 seed +=
hash_uint2((
int)(b_scene.frame_subframe() * (
float)INT_MAX),
335 integrator->set_seed(
seed);
337 integrator->set_sample_clamp_direct(
get_float(cscene,
"sample_clamp_direct"));
338 integrator->set_sample_clamp_indirect(
get_float(cscene,
"sample_clamp_indirect"));
340 integrator->set_motion_blur(view_layer.use_motion_blur);
343 integrator->set_light_sampling_threshold(
get_float(cscene,
"light_sampling_threshold"));
347 integrator->set_sampling_pattern(sampling_pattern);
350 bool use_adaptive_sampling =
false;
352 samples =
get_int(cscene,
"preview_samples");
353 use_adaptive_sampling =
RNA_boolean_get(&cscene,
"use_preview_adaptive_sampling");
354 integrator->set_use_adaptive_sampling(use_adaptive_sampling);
355 integrator->set_adaptive_threshold(
get_float(cscene,
"preview_adaptive_threshold"));
356 integrator->set_adaptive_min_samples(
get_int(cscene,
"preview_adaptive_min_samples"));
359 samples =
get_int(cscene,
"samples");
360 use_adaptive_sampling =
RNA_boolean_get(&cscene,
"use_adaptive_sampling");
361 integrator->set_use_adaptive_sampling(use_adaptive_sampling);
362 integrator->set_adaptive_threshold(
get_float(cscene,
"adaptive_threshold"));
363 integrator->set_adaptive_min_samples(
get_int(cscene,
"adaptive_min_samples"));
366 float scrambling_distance =
get_float(cscene,
"scrambling_distance");
367 bool auto_scrambling_distance =
get_boolean(cscene,
"auto_scrambling_distance");
368 if (auto_scrambling_distance) {
377 if (use_adaptive_sampling) {
383 scrambling_distance *= 4.0f /
sqrtf(samples);
387 bool preview_scrambling_distance =
get_boolean(cscene,
"preview_scrambling_distance");
388 if (preview && !preview_scrambling_distance) {
389 scrambling_distance = 1.0f;
392 if (scrambling_distance != 1.0f) {
393 VLOG_INFO <<
"Using scrambling distance: " << scrambling_distance;
395 integrator->set_scrambling_distance(scrambling_distance);
399 integrator->set_ao_bounces(
get_int(cscene,
"ao_bounces"));
402 integrator->set_ao_bounces(
get_int(cscene,
"ao_bounces_render"));
406 integrator->set_ao_bounces(0);
409 #ifdef WITH_CYCLES_DEBUG
412 integrator->set_direct_light_sampling_type(direct_light_sampling_type);
420 b_scene.render().bake().target() != BL::BakeSettings::target_IMAGE_TEXTURES) {
421 denoise_params.
use =
false;
424 integrator->set_use_denoise(denoise_params.
use);
429 if (denoise_params.
use) {
430 integrator->set_denoiser_type(denoise_params.
type);
431 integrator->set_denoise_start_sample(denoise_params.
start_sample);
432 integrator->set_use_denoise_pass_albedo(denoise_params.
use_pass_albedo);
433 integrator->set_use_denoise_pass_normal(denoise_params.
use_pass_normal);
434 integrator->set_denoiser_prefilter(denoise_params.
prefilter);
444 void BlenderSync::sync_film(
BL::ViewLayer &b_view_layer, BL::SpaceView3D &b_v3d)
453 film->set_display_pass(new_viewport_parameters.display_pass);
454 film->set_show_active_pixels(new_viewport_parameters.show_active_pixels);
457 film->set_exposure(
get_float(cscene,
"film_exposure"));
458 film->set_filter_type(
460 float filter_width = (film->get_filter_type() ==
FILTER_BOX) ? 1.0f :
462 film->set_filter_width(filter_width);
464 if (b_scene.world()) {
465 BL::WorldMistSettings b_mist = b_scene.world().mist_settings();
467 film->set_mist_start(b_mist.start());
468 film->set_mist_depth(b_mist.depth());
470 switch (b_mist.falloff()) {
471 case BL::WorldMistSettings::falloff_QUADRATIC:
472 film->set_mist_falloff(2.0f);
474 case BL::WorldMistSettings::falloff_LINEAR:
475 film->set_mist_falloff(1.0f);
477 case BL::WorldMistSettings::falloff_INVERSE_QUADRATIC:
478 film->set_mist_falloff(0.5f);
486 film->set_use_approximate_shadow_catcher(
true);
489 film->set_use_approximate_shadow_catcher(!
get_boolean(crl,
"use_pass_shadow_catcher"));
497 view_layer.name = b_view_layer.name();
500 view_layer.use_background_shader = b_view_layer.use_sky();
503 view_layer.use_hair = b_view_layer.use_strand();
504 view_layer.use_volumes = b_view_layer.use_volumes();
505 view_layer.use_motion_blur = b_view_layer.use_motion_blur() &&
506 b_scene.render().use_motion_blur();
509 view_layer.material_override = b_view_layer.material_override();
513 int use_layer_samples =
get_enum(cscene,
"use_layer_samples");
515 view_layer.bound_samples = (use_layer_samples == 1);
516 view_layer.samples = 0;
518 if (use_layer_samples != 2) {
519 int samples = b_view_layer.samples();
520 view_layer.samples = samples;
525 void BlenderSync::sync_images()
529 const bool is_interface_locked = b_engine.render() && b_engine.render().use_lock_interface();
537 for (
BL::Image &b_image : b_data.images) {
541 const bool is_builtin = b_image.packed_file() ||
542 b_image.source() == BL::Image::source_GENERATED ||
543 b_image.source() == BL::Image::source_MOVIE || b_engine.is_preview();
545 b_image.buffers_free();
555 string name = b_pass.name();
556 #define MAP_PASS(passname, passtype) \
557 if (name == passname) { \
624 pass->set_type(
type);
625 pass->set_name(ustring(name));
626 pass->set_mode(mode);
636 set<Pass *> clear_passes(scene->
passes.begin(), scene->
passes.end());
647 LOG(ERROR) <<
"Unknown pass " << b_pass.name();
652 (b_view_layer.use_motion_blur() && b_scene.render().use_motion_blur())) {
663 b_engine.add_pass(
"Debug Sample Count", 1,
"X", b_view_layer.name().c_str());
669 b_engine.add_pass(
"VolumeDir", 3,
"RGB", b_view_layer.name().c_str());
672 if (
get_boolean(crl,
"use_pass_volume_indirect")) {
673 b_engine.add_pass(
"VolumeInd", 3,
"RGB", b_view_layer.name().c_str());
677 b_engine.add_pass(
"Shadow Catcher", 3,
"RGB", b_view_layer.name().c_str());
687 int crypto_depth =
divide_up(
min(16, b_view_layer.pass_cryptomatte_depth()), 2);
688 scene->
film->set_cryptomatte_depth(crypto_depth);
690 if (b_view_layer.use_pass_cryptomatte_object()) {
691 for (
int i = 0; i < crypto_depth; i++) {
693 b_engine.add_pass(passname.c_str(), 4,
"rgba", b_view_layer.name().c_str());
698 if (b_view_layer.use_pass_cryptomatte_material()) {
699 for (
int i = 0; i < crypto_depth; i++) {
701 b_engine.add_pass(passname.c_str(), 4,
"rgba", b_view_layer.name().c_str());
706 if (b_view_layer.use_pass_cryptomatte_asset()) {
707 for (
int i = 0; i < crypto_depth; i++) {
709 b_engine.add_pass(passname.c_str(), 4,
"rgba", b_view_layer.name().c_str());
714 scene->
film->set_cryptomatte_passes(cryptomatte_passes);
717 const bool use_denoising =
get_boolean(cscene,
"use_denoising") &&
719 const bool store_denoising_passes =
get_boolean(crl,
"denoising_store_passes");
721 b_engine.add_pass(
"Noisy Image", 4,
"RGBA", b_view_layer.name().c_str());
724 b_engine.add_pass(
"Noisy Shadow Catcher", 3,
"RGB", b_view_layer.name().c_str());
728 if (store_denoising_passes) {
729 b_engine.add_pass(
"Denoising Normal", 3,
"XYZ", b_view_layer.name().c_str());
732 b_engine.add_pass(
"Denoising Albedo", 3,
"RGB", b_view_layer.name().c_str());
735 b_engine.add_pass(
"Denoising Depth", 1,
"Z", b_view_layer.name().c_str());
740 BL::ViewLayer::aovs_iterator b_aov_iter;
741 for (b_view_layer.aovs.begin(b_aov_iter); b_aov_iter != b_view_layer.aovs.end(); ++b_aov_iter) {
742 BL::AOV b_aov(*b_aov_iter);
743 if (!b_aov.is_valid()) {
747 string name = b_aov.name();
748 bool is_color = b_aov.type() == BL::AOV::type_COLOR;
751 b_engine.add_pass(name.c_str(), 4,
"RGBA", b_view_layer.name().c_str());
755 b_engine.add_pass(name.c_str(), 1,
"X", b_view_layer.name().c_str());
761 BL::ViewLayer::lightgroups_iterator b_lightgroup_iter;
762 for (b_view_layer.lightgroups.begin(b_lightgroup_iter);
763 b_lightgroup_iter != b_view_layer.lightgroups.end();
764 ++b_lightgroup_iter) {
765 BL::Lightgroup b_lightgroup(*b_lightgroup_iter);
767 string name =
string_printf(
"Combined_%s", b_lightgroup.name().c_str());
769 b_engine.add_pass(name.c_str(), 3,
"RGB", b_view_layer.name().c_str());
771 pass->set_lightgroup(ustring(b_lightgroup.name()));
774 scene->
film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold());
777 void BlenderSync::free_data_after_sync(
BL::Depsgraph &b_depsgraph)
784 const bool is_interface_locked = b_engine.render() && b_engine.render().use_lock_interface();
785 const bool is_persistent_data = b_engine.render() && b_engine.render().use_persistent_data();
786 const bool can_free_caches =
795 if (!can_free_caches) {
801 for (
BL::Object &b_ob : b_depsgraph.objects) {
802 b_ob.cache_release();
814 if (shadingsystem == 0)
816 else if (shadingsystem == 1)
819 if (background ||
DebugFlags().viewport_static_bvh)
836 texture_limit =
RNA_enum_get(&cscene,
"texture_limit_render");
841 if (texture_limit > 0 && b_scene.render().use_simplify()) {
842 params.texture_limit = 1 << (texture_limit + 6);
850 params.background = background;
860 return (background) ? false :
get_boolean(cscene,
"preview_pause");
864 BL::Preferences &b_preferences,
871 if (background && !b_engine.is_preview()) {
876 params.temp_dir = b_engine.temporary_directory();
884 params.background = background;
891 int samples =
get_int(cscene,
"samples");
892 int preview_samples =
get_int(cscene,
"preview_samples");
893 int sample_offset =
get_int(cscene,
"sample_offset");
897 params.sample_offset = sample_offset;
900 params.samples = preview_samples;
901 if (
params.samples == 0) {
914 params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
923 if (shadingsystem == 0)
925 else if (shadingsystem == 1)
941 params.use_profiling =
params.device.has_profiling && !b_engine.is_preview() && background &&
949 params.use_auto_tile =
false;
960 DENOISER_INPUT_RGB = 1,
961 DENOISER_INPUT_RGB_ALBEDO = 2,
962 DENOISER_INPUT_RGB_ALBEDO_NORMAL = 3,
970 int input_passes = -1;
979 input_passes = (DenoiserInput)
get_enum(
980 cscene,
"denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO_NORMAL);
985 denoising.
use =
false;
998 input_passes = (DenoiserInput)
get_enum(
999 cscene,
"preview_denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO);
1010 denoising.
use =
false;
1015 switch (input_passes) {
1016 case DENOISER_INPUT_RGB:
1021 case DENOISER_INPUT_RGB_ALBEDO:
1026 case DENOISER_INPUT_RGB_ALBEDO_NORMAL:
1032 LOG(ERROR) <<
"Unhandled input passes enum " << input_passes;
typedef double(DMatrix)[4][4]
struct Depsgraph Depsgraph
struct ViewLayer ViewLayer
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
struct RenderEngine RenderEngine
struct RenderLayer RenderLayer
struct RenderPass RenderPass
int blender_device_threads(BL::Scene &b_scene)
DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, bool background)
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)
static bool get_session_pause(BL::Scene &b_scene, bool background)
void sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d)
static SceneParams get_scene_params(BL::Scene &b_scene, bool background)
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_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)
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)
void sync_integrator(BL::ViewLayer &b_view_layer, bool background)
bool shader_modified(const BlenderViewportParameters &other) const
bool modified(const BlenderViewportParameters &other) const
DenoiserPrefilter prefilter
static vector< DeviceInfo > available_devices(uint device_type_mask=DEVICE_MASK_ALL)
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
const map< K, T * > & key_to_scene_data()
void set_recalc(const BL::ID &id)
void post_sync(bool do_delete=true)
#define CCL_NAMESPACE_END
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_PREFILTER_FAST
@ DENOISER_PREFILTER_NONE
@ DENOISER_OPENIMAGEDENOISE
ccl_device_inline uint hash_uint2(uint kx, uint ky)
@ DIRECT_LIGHT_SAMPLING_MIS
@ DIRECT_LIGHT_SAMPLING_NUM
@ PASS_TRANSMISSION_DIRECT
@ PASS_TRANSMISSION_COLOR
@ PASS_TRANSMISSION_INDIRECT
@ PASS_ADAPTIVE_AUX_BUFFER
bool is_builtin(const void *UNUSED(owner), const AttributeIDRef &attribute_id)
T clamp(const T &a, const T &min, const T &max)
static const pxr::TfToken preview("preview", pxr::TfToken::Immortal)
static CCL_NAMESPACE_BEGIN bool openimagedenoise_supported()
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
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)
bool string_startswith(const string_view s, const string_view start)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
BakeManager * bake_manager
T * create_node(Args &&...args)
MotionType need_motion() const
ImageManager * image_manager
void delete_nodes(const set< T * > &nodes)
static PassType get_blender_pass_type(BL::RenderPass &b_pass)
static Pass * pass_add(Scene *scene, PassType type, const char *name, PassMode mode=PassMode::DENOISED)
static CCL_NAMESPACE_BEGIN const char * cryptomatte_prefix
#define MAP_PASS(passname, passtype)
ccl_device_inline size_t divide_up(size_t x, size_t y)