diff options
Diffstat (limited to 'intern/cycles/blender/shader.cpp')
-rw-r--r-- | intern/cycles/blender/shader.cpp | 141 |
1 files changed, 123 insertions, 18 deletions
diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp index 81a64457c88..9505f4ba58f 100644 --- a/intern/cycles/blender/shader.cpp +++ b/intern/cycles/blender/shader.cpp @@ -248,6 +248,13 @@ static void get_tex_mapping(TextureNode *mapping, BL::TexMapping &b_mapping) mapping->set_tex_mapping_z_mapping((TextureMapping::Mapping)b_mapping.mapping_z()); } +static bool is_image_animated(BL::Image::source_enum b_image_source, BL::ImageUser &b_image_user) +{ + return (b_image_source == BL::Image::source_MOVIE || + b_image_source == BL::Image::source_SEQUENCE) && + b_image_user.use_auto_refresh(); +} + static ShaderNode *add_node(Scene *scene, BL::RenderEngine &b_engine, BL::BlendData &b_data, @@ -343,6 +350,33 @@ static ShaderNode *add_node(Scene *scene, mix->set_use_clamp(b_mix_node.use_clamp()); node = mix; } + else if (b_node.is_a(&RNA_ShaderNodeMix)) { + BL::ShaderNodeMix b_mix_node(b_node); + if (b_mix_node.data_type() == BL::ShaderNodeMix::data_type_VECTOR) { + if (b_mix_node.factor_mode() == BL::ShaderNodeMix::factor_mode_UNIFORM) { + MixVectorNode *mix_node = graph->create_node<MixVectorNode>(); + mix_node->set_use_clamp(b_mix_node.clamp_factor()); + node = mix_node; + } + else { + MixVectorNonUniformNode *mix_node = graph->create_node<MixVectorNonUniformNode>(); + mix_node->set_use_clamp(b_mix_node.clamp_factor()); + node = mix_node; + } + } + else if (b_mix_node.data_type() == BL::ShaderNodeMix::data_type_RGBA) { + MixColorNode *mix_node = graph->create_node<MixColorNode>(); + mix_node->set_blend_type((NodeMix)b_mix_node.blend_type()); + mix_node->set_use_clamp(b_mix_node.clamp_factor()); + mix_node->set_use_clamp_result(b_mix_node.clamp_result()); + node = mix_node; + } + else { + MixFloatNode *mix_node = graph->create_node<MixFloatNode>(); + mix_node->set_use_clamp(b_mix_node.clamp_factor()); + node = mix_node; + } + } else if (b_node.is_a(&RNA_ShaderNodeSeparateRGB)) { node = graph->create_node<SeparateRGBNode>(); } @@ -748,10 +782,11 @@ static ShaderNode *add_node(Scene *scene, get_tex_mapping(image, b_texture_mapping); if (b_image) { + BL::Image::source_enum b_image_source = b_image.source(); PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr; image->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name"))); - image->set_animated(b_image_node.image_user().use_auto_refresh()); + image->set_animated(is_image_animated(b_image_source, b_image_user)); image->set_alpha_type(get_image_alpha_type(b_image)); array<int> tiles; @@ -763,9 +798,9 @@ static ShaderNode *add_node(Scene *scene, /* builtin images will use callback-based reading because * they could only be loaded correct from blender side */ - bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED || - b_image.source() == BL::Image::source_MOVIE || - (b_engine.is_preview() && b_image.source() != BL::Image::source_SEQUENCE); + bool is_builtin = b_image.packed_file() || b_image_source == BL::Image::source_GENERATED || + b_image_source == BL::Image::source_MOVIE || + (b_engine.is_preview() && b_image_source != BL::Image::source_SEQUENCE); if (is_builtin) { /* for builtin images we're using image datablock name to find an image to @@ -776,7 +811,7 @@ static ShaderNode *add_node(Scene *scene, */ int scene_frame = b_scene.frame_current(); int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame); - if (b_image.source() != BL::Image::source_TILED) { + if (b_image_source != BL::Image::source_TILED) { image->handle = scene->image_manager->add_image( new BlenderImageLoader(b_image, image_frame, 0, b_engine.is_preview()), image->image_params()); @@ -794,7 +829,7 @@ static ShaderNode *add_node(Scene *scene, } else { ustring filename = ustring( - image_user_file_path(b_image_user, b_image, b_scene.frame_current())); + image_user_file_path(b_data, b_image_user, b_image, b_scene.frame_current())); image->set_filename(filename); } } @@ -812,15 +847,15 @@ static ShaderNode *add_node(Scene *scene, get_tex_mapping(env, b_texture_mapping); if (b_image) { + BL::Image::source_enum b_image_source = b_image.source(); PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr; env->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name"))); - - env->set_animated(b_env_node.image_user().use_auto_refresh()); + env->set_animated(is_image_animated(b_image_source, b_image_user)); env->set_alpha_type(get_image_alpha_type(b_image)); - bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED || - b_image.source() == BL::Image::source_MOVIE || - (b_engine.is_preview() && b_image.source() != BL::Image::source_SEQUENCE); + bool is_builtin = b_image.packed_file() || b_image_source == BL::Image::source_GENERATED || + b_image_source == BL::Image::source_MOVIE || + (b_engine.is_preview() && b_image_source != BL::Image::source_SEQUENCE); if (is_builtin) { int scene_frame = b_scene.frame_current(); @@ -831,7 +866,7 @@ static ShaderNode *add_node(Scene *scene, } else { env->set_filename( - ustring(image_user_file_path(b_image_user, b_image, b_scene.frame_current()))); + ustring(image_user_file_path(b_data, b_image_user, b_image, b_scene.frame_current()))); } } node = env; @@ -928,8 +963,22 @@ static ShaderNode *add_node(Scene *scene, sky->set_sun_disc(b_sky_node.sun_disc()); sky->set_sun_size(b_sky_node.sun_size()); sky->set_sun_intensity(b_sky_node.sun_intensity()); - sky->set_sun_elevation(b_sky_node.sun_elevation()); - sky->set_sun_rotation(b_sky_node.sun_rotation()); + /* Patch sun position to be able to animate daylight cycle while keeping the shading code + * simple. */ + float sun_rotation = b_sky_node.sun_rotation(); + /* Wrap into [-2PI..2PI] range. */ + float sun_elevation = fmodf(b_sky_node.sun_elevation(), M_2PI_F); + /* Wrap into [-PI..PI] range. */ + if (fabsf(sun_elevation) >= M_PI_F) { + sun_elevation -= copysignf(2.0f, sun_elevation) * M_PI_F; + } + /* Wrap into [-PI/2..PI/2] range while keeping the same absolute position. */ + if (sun_elevation >= M_PI_2_F || sun_elevation <= -M_PI_2_F) { + sun_elevation = copysignf(M_PI_F, sun_elevation) - sun_elevation; + sun_rotation += M_PI_F; + } + sky->set_sun_elevation(sun_elevation); + sky->set_sun_rotation(sun_rotation); sky->set_altitude(b_sky_node.altitude()); sky->set_air_density(b_sky_node.air_density()); sky->set_dust_density(b_sky_node.dust_density()); @@ -1050,7 +1099,9 @@ static bool node_use_modified_socket_name(ShaderNode *node) return true; } -static ShaderInput *node_find_input_by_name(ShaderNode *node, BL::NodeSocket &b_socket) +static ShaderInput *node_find_input_by_name(BL::Node b_node, + ShaderNode *node, + BL::NodeSocket &b_socket) { string name = b_socket.identifier(); ShaderInput *input = node->input(name.c_str()); @@ -1060,6 +1111,35 @@ static ShaderInput *node_find_input_by_name(ShaderNode *node, BL::NodeSocket &b_ if (string_startswith(name, "Shader")) { string_replace(name, "Shader", "Closure"); } + + /* Map mix node internal name for shader. */ + if (b_node.is_a(&RNA_ShaderNodeMix)) { + if (string_endswith(name, "Factor_Float")) { + string_replace(name, "Factor_Float", "Factor"); + } + else if (string_endswith(name, "Factor_Vector")) { + string_replace(name, "Factor_Vector", "Factor"); + } + else if (string_endswith(name, "A_Float")) { + string_replace(name, "A_Float", "A"); + } + else if (string_endswith(name, "B_Float")) { + string_replace(name, "B_Float", "B"); + } + else if (string_endswith(name, "A_Color")) { + string_replace(name, "A_Color", "A"); + } + else if (string_endswith(name, "B_Color")) { + string_replace(name, "B_Color", "B"); + } + else if (string_endswith(name, "A_Vector")) { + string_replace(name, "A_Vector", "A"); + } + else if (string_endswith(name, "B_Vector")) { + string_replace(name, "B_Vector", "B"); + } + } + input = node->input(name.c_str()); if (!input) { @@ -1089,7 +1169,9 @@ static ShaderInput *node_find_input_by_name(ShaderNode *node, BL::NodeSocket &b_ return input; } -static ShaderOutput *node_find_output_by_name(ShaderNode *node, BL::NodeSocket &b_socket) +static ShaderOutput *node_find_output_by_name(BL::Node b_node, + ShaderNode *node, + BL::NodeSocket &b_socket) { string name = b_socket.identifier(); ShaderOutput *output = node->output(name.c_str()); @@ -1100,6 +1182,21 @@ static ShaderOutput *node_find_output_by_name(ShaderNode *node, BL::NodeSocket & name = "Closure"; output = node->output(name.c_str()); } + /* Map internal name for shader. */ + if (b_node.is_a(&RNA_ShaderNodeMix)) { + if (string_endswith(name, "Result_Float")) { + string_replace(name, "Result_Float", "Result"); + output = node->output(name.c_str()); + } + else if (string_endswith(name, "Result_Color")) { + string_replace(name, "Result_Color", "Result"); + output = node->output(name.c_str()); + } + else if (string_endswith(name, "Result_Vector")) { + string_replace(name, "Result_Vector", "Result"); + output = node->output(name.c_str()); + } + } } return output; @@ -1245,7 +1342,11 @@ static void add_nodes(Scene *scene, if (node) { /* map node sockets for linking */ for (BL::NodeSocket &b_input : b_node.inputs) { - ShaderInput *input = node_find_input_by_name(node, b_input); + if (b_input.is_unavailable()) { + /* Skip unavailable sockets. */ + continue; + } + ShaderInput *input = node_find_input_by_name(b_node, node, b_input); if (!input) { /* XXX should not happen, report error? */ continue; @@ -1255,7 +1356,11 @@ static void add_nodes(Scene *scene, set_default_value(input, b_input, b_data, b_ntree); } for (BL::NodeSocket &b_output : b_node.outputs) { - ShaderOutput *output = node_find_output_by_name(node, b_output); + if (b_output.is_unavailable()) { + /* Skip unavailable sockets. */ + continue; + } + ShaderOutput *output = node_find_output_by_name(b_node, node, b_output); if (!output) { /* XXX should not happen, report error? */ continue; |