29# include <OpenColorIO/OpenColorIO.h>
30namespace OCIO = OCIO_NAMESPACE;
33#include "scene/shader.tables"
45 static NodeEnum emission_sampling_method_enum;
52 "Emission Sampling Method",
53 emission_sampling_method_enum,
56 SOCKET_BOOLEAN(use_transparent_shadow,
"Use Transparent Shadow",
true);
57 SOCKET_BOOLEAN(use_bump_map_correction,
"Bump Map Correction",
true);
58 SOCKET_BOOLEAN(heterogeneous_volume,
"Heterogeneous Volume",
true);
60 static NodeEnum volume_sampling_method_enum;
65 "Volume Sampling Method",
66 volume_sampling_method_enum,
69 static NodeEnum volume_interpolation_method_enum;
73 "Volume Interpolation Method",
74 volume_interpolation_method_enum,
77 SOCKET_FLOAT(volume_step_rate,
"Volume Step Rate", 1.0f);
79 static NodeEnum displacement_method_enum;
133 if (node ==
nullptr) {
136 else if (node->type == EmissionNode::get_node_type() ||
137 node->type == BackgroundNode::get_node_type() ||
138 node->type == PrincipledBsdfNode::get_node_type())
140 const bool is_principled = (node->type == PrincipledBsdfNode::get_node_type());
142 ShaderInput *color_in = node->input(is_principled ?
"Emission Color" :
"Color");
143 ShaderInput *strength_in = node->input(is_principled ?
"Emission Strength" :
"Strength");
152 if (color_in->
link) {
156 estimate *= node->get_float3(color_in->
socket_type);
159 if (strength_in->
link) {
164 estimate *= node->get_float(strength_in->
socket_type);
170 if (node->type == EmissionNode::get_node_type()) {
179 else if (node->type == LightFalloffNode::get_node_type() ||
180 node->type == IESLightNode::get_node_type())
183 ShaderInput *strength_in = node->input(
"Strength");
189 else if (node->type == AddClosureNode::get_node_type()) {
191 ShaderInput *closure1_in = node->input(
"Closure1");
192 ShaderInput *closure2_in = node->input(
"Closure2");
194 const float3 estimate1 = (closure1_in->
link) ?
197 const float3 estimate2 = (closure2_in->
link) ?
201 return estimate1 + estimate2;
203 else if (node->type == MixClosureNode::get_node_type()) {
206 ShaderInput *closure1_in = node->input(
"Closure1");
207 ShaderInput *closure2_in = node->input(
"Closure2");
209 const float3 estimate1 = (closure1_in->
link) ?
212 const float3 estimate2 = (closure2_in->
link) ?
218 return estimate1 + estimate2;
221 const float fac = node->get_float(fac_in->
socket_type);
222 return (1.0f - fac) * estimate1 + fac * estimate2;
228 const bool has_emission = node->has_surface_emission();
266 ShaderInput *surf = graph->output()->input(
"Surface");
301 const char *old_hash = (
graph) ? graph->displacement_hash.c_str() :
"";
304 if (strcmp(old_hash, new_hash) != 0) {
336 if (
this == scene->background->get_shader(scene)) {
337 scene->light_manager->need_update_background =
true;
338 if (scene->light_manager->has_background_light(scene)) {
360 graph->add(transparent);
361 graph->connect(transparent->output(
"BSDF"), output->input(
"Surface"));
382 node->attributes(
this, &attributes);
389 if (displacement_method_is_modified()) {
392 scene->object_manager->need_flags_update =
true;
398 if (attributes.modified(prev_attributes)) {
401 scene->procedural_manager->tag_update();
405 scene->geometry_manager->need_flags_update =
true;
406 scene->object_manager->need_flags_update =
true;
447 manager =
new OSLShaderManager(device);
505 foreach (
Shader *shader, scene->shaders) {
511 assert(scene->default_surface->reference_count() != 0);
512 assert(scene->default_light->reference_count() != 0);
513 assert(scene->default_background->reference_count() != 0);
514 assert(scene->default_empty->reference_count() != 0);
526 if (scene->shaders.size() == 0) {
531 bool has_volumes =
false;
532 bool has_transparent_shadow =
false;
534 foreach (
Shader *shader, scene->shaders) {
547 if (!
is_zero(shader->emission_estimate)) {
550 if (shader->has_surface_transparent && shader->get_use_transparent_shadow()) {
553 if (shader->has_surface_raytrace) {
556 if (shader->has_volume) {
566 if (shader->has_volume_connected && !shader->has_surface) {
569 if (shader->has_volume) {
570 if (shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) {
574 if (shader->has_volume_attribute_dependency) {
577 if (shader->has_bssrdf_bump) {
589 if (shader->has_bump) {
595 if (shader->get_use_bump_map_correction()) {
600 if (shader->emission_is_constant) {
608 kshader->
pass_id = shader->get_pass_id();
633 KernelIntegrator *kintegrator = &dscene->
data.integrator;
634 kintegrator->use_volumes = has_volumes;
636 kintegrator->transparent_shadows = has_transparent_shadow;
639 KernelFilm *kfilm = &dscene->
data.film;
655 scene->lookup_tables->remove_table(&entry.second);
672 graph->connect(diffuse->output(
"BSDF"), graph->output()->input(
"Surface"));
675 shader->
name =
"default_surface";
676 shader->set_graph(graph);
678 scene->default_surface = shader;
679 shader->tag_update(scene);
687 graph->add(principled);
689 graph->connect(principled->
output(
"Volume"), graph->output()->input(
"Volume"));
692 shader->
name =
"default_volume";
693 shader->set_graph(graph);
694 scene->default_volume = shader;
695 shader->tag_update(scene);
705 emission->set_color(
make_float3(0.8f, 0.8f, 0.8f));
706 emission->set_strength(0.0f);
707 graph->add(emission);
709 graph->connect(emission->output(
"Emission"), graph->output()->input(
"Surface"));
712 shader->
name =
"default_light";
713 shader->set_graph(graph);
715 scene->default_light = shader;
716 shader->tag_update(scene);
724 shader->
name =
"default_background";
725 shader->set_graph(graph);
727 scene->default_background = shader;
728 shader->tag_update(scene);
736 shader->
name =
"default_empty";
737 shader->set_graph(graph);
739 scene->default_empty = shader;
740 shader->tag_update(scene);
746 uint kernel_features = 0;
749 kernel_features |= node->get_feature();
756 if (node->has_surface_bssrdf()) {
759 if (node->has_surface_transparent()) {
764 return kernel_features;
770 for (
int i = 0; i < scene->shaders.size(); i++) {
771 Shader *shader = scene->shaders[i];
772 if (!shader->reference_count()) {
787 if (shader->has_volume_connected) {
796 return kernel_features;
803 OSLShaderManager::free_memory();
821 string manifest =
"{";
822 unordered_set<ustring, ustringHash> materials;
823 foreach (
Shader *shader, scene->shaders) {
824 if (materials.count(shader->name)) {
827 materials.insert(shader->name);
829 manifest +=
string_printf(
"\"%s\":\"%08x\",", shader->name.c_str(), cryptomatte_id);
831 manifest[manifest.size() - 1] =
'}';
847static bool to_scene_linear_transform(OCIO::ConstConfigRcPtr &config,
848 const char *colorspace,
851 OCIO::ConstProcessorRcPtr processor;
853 processor = config->getProcessor(
"scene_linear", colorspace);
855 catch (OCIO::Exception &) {
863 OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
864 if (!device_processor) {
869 device_processor->applyRGB(&to_scene_linear.
x.x);
870 device_processor->applyRGB(&to_scene_linear.
y.x);
871 device_processor->applyRGB(&to_scene_linear.
z.x);
907 OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
908 if (!(config && config->hasRole(
"scene_linear"))) {
914 if (config->hasRole(
"aces_interchange")) {
917 if (!to_scene_linear_transform(config,
"aces_interchange", aces_to_rgb)) {
938 else if (config->hasRole(
"XYZ")) {
940 if (!to_scene_linear_transform(config,
"XYZ",
xyz_to_rgb)) {
973 bsdf_tables[table] = scene->lookup_tables->add_table(dscene, entries);
virtual ClosureType get_closure_type()
static void free_memory()
device_vector< KernelShader > shaders
bool from_auto_conversion
@ SHADER_DISPLACEMENT_MODIFIED
@ SHADER_ATTRIBUTE_MODIFIED
void compute_displacement_hash()
void remove_proxy_nodes()
string get_cryptomatte_materials(Scene *scene)
static ShaderManager * create(int shadingsystem, Device *device)
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
static void free_memory()
AttributeIDMap unique_attribute_id
float linear_rgb_to_gray(float3 c)
virtual uint64_t get_attribute_id(ustring name)
void init_xyz_transforms()
virtual void device_update_specific(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)=0
thread_spin_lock attribute_lock_
int get_shader_id(Shader *shader, bool smooth=false)
unordered_map< const float *, size_t > bsdf_tables
void device_free_common(Device *device, DeviceScene *dscene, Scene *scene)
static thread_mutex lookup_table_mutex
void tag_update(Scene *scene, uint32_t flag)
uint get_kernel_features(Scene *scene)
size_t ensure_bsdf_table_impl(DeviceScene *dscene, Scene *scene, const float *table, size_t n)
float3 rec709_to_scene_linear(float3 c)
size_t ensure_bsdf_table(DeviceScene *dscene, Scene *scene, const float(&table)[n])
static void add_default(Scene *scene)
uint get_graph_kernel_features(ShaderGraph *graph)
ShaderInput * input(const char *name)
ShaderOutput * output(const char *name)
bool has_surface_spatial_varying
bool need_update_attribute
bool has_volume_attribute_dependency
void set_graph(ShaderGraph *graph)
bool need_update_geometry() const
bool emission_is_constant
NODE_DECLARE ShaderGraph * graph
float prev_volume_step_rate
bool need_update_displacement
EmissionSampling emission_sampling
bool has_surface_raytrace
AttributeRequestSet attributes
bool has_surface_transparent
void tag_update(Scene *scene)
bool has_volume_connected
void tag_used(Scene *scene)
bool has_volume_spatial_varying
T * alloc(size_t width, size_t height=0, size_t depth=0)
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
#define CCL_NAMESPACE_END
#define CLOSURE_IS_VOLUME(type)
#define KERNEL_FEATURE_VOLUME
@ SD_HAS_TRANSPARENT_SHADOW
@ SD_HAS_CONSTANT_EMISSION
@ SD_NEED_VOLUME_ATTRIBUTES
@ SD_USE_BUMP_MAP_CORRECTION
@ SD_HETEROGENEOUS_VOLUME
#define KERNEL_FEATURE_NODE_BUMP_STATE
@ ATTR_STD_POSITION_UNDISPLACED
#define KERNEL_FEATURE_OSL
#define KERNEL_FEATURE_TRANSPARENT
@ EMISSION_SAMPLING_FRONT_BACK
@ EMISSION_SAMPLING_FRONT
#define KERNEL_FEATURE_SUBSURFACE
#define KERNEL_FEATURE_NODE_BSDF
#define KERNEL_FEATURE_NODE_VOLUME
#define KERNEL_FEATURE_NODE_EMISSION
#define KERNEL_FEATURE_NODE_BUMP
ccl_device float3 rec709_to_rgb(KernelGlobals kg, float3 rec709)
ccl_device_inline bool is_zero(const float2 a)
ccl_device_inline float reduce_max(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)
color xyz_to_rgb(float x, float y, float z)
#define SOCKET_FLOAT(name, ui_name, default_value,...)
#define SOCKET_INT(name, ui_name, default_value,...)
#define NODE_DEFINE(structname)
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
static float3 output_estimate_emission(ShaderOutput *output, bool &is_constant)
@ VOLUME_INTERPOLATION_LINEAR
@ VOLUME_INTERPOLATION_CUBIC
@ VOLUME_SAMPLING_DISTANCE
@ VOLUME_SAMPLING_EQUIANGULAR
@ VOLUME_SAMPLING_MULTIPLE_IMPORTANCE
@ SHADER_SPECIAL_TYPE_OUTPUT_AOV
@ SHADER_SPECIAL_TYPE_CLOSURE
unsigned __int64 uint64_t
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
float constant_emission[3]
int ggx_gen_schlick_ior_s
void insert(const char *x, int y)
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
int reference_count() const
CCL_NAMESPACE_BEGIN typedef std::mutex thread_mutex
ccl_device_inline float4 float3_to_float4(const float3 a)
ccl_device_inline float3 float4_to_float3(const float4 a)