Blender V5.0
blender/shader.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "scene/shader.h"
6#include "scene/background.h"
7#include "scene/integrator.h"
8#include "scene/light.h"
9#include "scene/osl.h"
10#include "scene/scene.h"
11#include "scene/shader_graph.h"
12#include "scene/shader_nodes.h"
13
14#include "blender/image.h"
15#include "blender/sync.h"
16#include "blender/util.h"
17
18#include "util/set.h"
19#include "util/string.h"
20#include "util/task.h"
21
22#include "BKE_duplilist.hh"
23#include "BKE_node.hh"
24
26
28
29using PtrInputMap = unordered_multimap<void *, ShaderInput *>;
30using PtrOutputMap = map<void *, ShaderOutput *>;
31using ProxyMap = map<string, ConvertNode *>;
32
33/* Find */
34
35void BlenderSync::find_shader(const BL::ID &id,
36 array<Node *> &used_shaders,
37 Shader *default_shader)
38{
39 Shader *synced_shader = (id) ? shader_map.find(id) : nullptr;
40 Shader *shader = (synced_shader) ? synced_shader : default_shader;
41
42 used_shaders.push_back_slow(shader);
43 shader->tag_used(scene);
44}
45
46/* RNA translation utilities */
47
53
59
65
66static int validate_enum_value(const int value, const int num_values, const int default_value)
67{
68 if (value >= num_values) {
69 return default_value;
70 }
71 return value;
72}
73
75{
76 const int value = b_mat.displacement_method();
78}
79
80template<typename NodeType> static InterpolationType get_image_interpolation(NodeType &b_node)
81{
82 const int value = b_node.interpolation();
85}
86
87template<typename NodeType> static ExtensionType get_image_extension(NodeType &b_node)
88{
89 const int value = b_node.extension();
91}
92
93static ImageAlphaType get_image_alpha_type(BL::Image &b_image)
94{
95 const int value = b_image.alpha_mode();
97}
98
99/* Attribute name translation utilities */
100
101/* Since Eevee needs to know whether the attribute is uniform or varying
102 * at the time it compiles the shader for the material, Blender had to
103 * introduce different namespaces (types) in its attribute node. However,
104 * Cycles already has object attributes that form a uniform namespace with
105 * the more common varying attributes. Without completely reworking the
106 * attribute handling in Cycles to introduce separate namespaces (this could
107 * be especially hard for OSL which directly uses the name string), the
108 * space identifier has to be added to the attribute name as a prefix.
109 *
110 * The prefixes include a control character to ensure the user specified
111 * name can't accidentally include a special prefix.
112 */
113
114static const string_view object_attr_prefix("\x01object:");
115static const string_view instancer_attr_prefix("\x01instancer:");
116static const string_view view_layer_attr_prefix("\x01layer:");
117
119{
120 switch (type) {
121 case BL::ShaderNodeAttribute::attribute_type_OBJECT:
122 return ustring::concat(object_attr_prefix, name);
123 case BL::ShaderNodeAttribute::attribute_type_INSTANCER:
124 return ustring::concat(instancer_attr_prefix, name);
125 case BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER:
126 return ustring::concat(view_layer_attr_prefix, name);
127 default:
128 return ustring(name);
129 }
130}
131
133{
134 const string_view sname(name);
135
136 if (sname.substr(0, object_attr_prefix.size()) == object_attr_prefix) {
137 *r_real_name = sname.substr(object_attr_prefix.size());
138 return BL::ShaderNodeAttribute::attribute_type_OBJECT;
139 }
140
141 if (sname.substr(0, instancer_attr_prefix.size()) == instancer_attr_prefix) {
142 *r_real_name = sname.substr(instancer_attr_prefix.size());
143 return BL::ShaderNodeAttribute::attribute_type_INSTANCER;
144 }
145
146 if (sname.substr(0, view_layer_attr_prefix.size()) == view_layer_attr_prefix) {
147 *r_real_name = sname.substr(view_layer_attr_prefix.size());
148 return BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER;
149 }
150
151 return BL::ShaderNodeAttribute::attribute_type_GEOMETRY;
152}
153
154/* Graph */
155
156static BL::NodeSocket get_node_output(BL::Node &b_node, const string &name)
157{
158 for (BL::NodeSocket &b_out : b_node.outputs) {
159 if (b_out.identifier() == name) {
160 return b_out;
161 }
162 }
163 assert(0);
164 return *b_node.outputs.begin();
165}
166
167static float3 get_node_output_rgba(BL::Node &b_node, const string &name)
168{
169 BL::NodeSocket b_sock = get_node_output(b_node, name);
170 float value[4];
171 RNA_float_get_array(&b_sock.ptr, "default_value", value);
172 return make_float3(value[0], value[1], value[2]);
173}
174
175static float get_node_output_value(BL::Node &b_node, const string &name)
176{
177 BL::NodeSocket b_sock = get_node_output(b_node, name);
178 return RNA_float_get(&b_sock.ptr, "default_value");
179}
180
181static float3 get_node_output_vector(BL::Node &b_node, const string &name)
182{
183 BL::NodeSocket b_sock = get_node_output(b_node, name);
184 float value[3];
185 RNA_float_get_array(&b_sock.ptr, "default_value", value);
186 return make_float3(value[0], value[1], value[2]);
187}
188
189static SocketType::Type convert_socket_type(BL::NodeSocket &b_socket)
190{
191 switch (b_socket.type()) {
192 case BL::NodeSocket::type_VALUE:
193 return SocketType::FLOAT;
194 case BL::NodeSocket::type_BOOLEAN:
195 case BL::NodeSocket::type_INT:
196 return SocketType::INT;
197 case BL::NodeSocket::type_VECTOR:
198 return SocketType::VECTOR;
199 case BL::NodeSocket::type_RGBA:
200 return SocketType::COLOR;
201 case BL::NodeSocket::type_STRING:
202 return SocketType::STRING;
203 case BL::NodeSocket::type_SHADER:
204 return SocketType::CLOSURE;
205
206 default:
208 }
209}
210
212 BL::NodeSocket &b_sock,
213 BL::BlendData &b_data,
214 BL::ID &b_id)
215{
216 Node *node = input->parent;
217 const SocketType &socket = input->socket_type;
218
219 /* copy values for non linked inputs */
220 switch (input->type()) {
221 case SocketType::FLOAT: {
222 node->set(socket, get_float(b_sock.ptr, "default_value"));
223 break;
224 }
225 case SocketType::INT: {
226 if (b_sock.type() == BL::NodeSocket::type_BOOLEAN) {
227 /* Make sure to call the int overload of set() since this is an integer socket as far as
228 * Cycles is concerned. */
229 node->set(socket, get_boolean(b_sock.ptr, "default_value") ? 1 : 0);
230 }
231 else {
232 node->set(socket, get_int(b_sock.ptr, "default_value"));
233 }
234 break;
235 }
236 case SocketType::COLOR: {
237 node->set(socket, make_float3(get_float4(b_sock.ptr, "default_value")));
238 break;
239 }
242 case SocketType::VECTOR: {
243 node->set(socket, get_float3(b_sock.ptr, "default_value"));
244 break;
245 }
246 case SocketType::STRING: {
247 node->set(
248 socket,
249 (ustring)blender_absolute_path(b_data, b_id, get_string(b_sock.ptr, "default_value")));
250 break;
251 }
252 default:
253 break;
254 }
255}
256
257static void get_tex_mapping(TextureNode *mapping, BL::TexMapping &b_mapping)
258{
259 if (!b_mapping) {
260 return;
261 }
262
263 mapping->set_tex_mapping_translation(get_float3(b_mapping.translation()));
264 mapping->set_tex_mapping_rotation(get_float3(b_mapping.rotation()));
265 mapping->set_tex_mapping_scale(get_float3(b_mapping.scale()));
266 mapping->set_tex_mapping_type((TextureMapping::Type)b_mapping.vector_type());
267
268 mapping->set_tex_mapping_x_mapping((TextureMapping::Mapping)b_mapping.mapping_x());
269 mapping->set_tex_mapping_y_mapping((TextureMapping::Mapping)b_mapping.mapping_y());
270 mapping->set_tex_mapping_z_mapping((TextureMapping::Mapping)b_mapping.mapping_z());
271}
272
273static bool is_image_animated(BL::Image::source_enum b_image_source, BL::ImageUser &b_image_user)
274{
275 return (b_image_source == BL::Image::source_MOVIE ||
276 b_image_source == BL::Image::source_SEQUENCE) &&
277 b_image_user.use_auto_refresh();
278}
279
280static ShaderNode *add_node(Scene *scene,
281 BL::RenderEngine &b_engine,
282 BL::BlendData &b_data,
283 BL::Scene &b_scene,
284 ShaderGraph *graph,
285 BL::ShaderNodeTree &b_ntree,
286 BL::ShaderNode &b_node)
287{
288 ShaderNode *node = nullptr;
289
290 /* existing blender nodes */
291 if (b_node.is_a(&RNA_ShaderNodeRGBCurve)) {
292 BL::ShaderNodeRGBCurve b_curve_node(b_node);
293 BL::CurveMapping mapping(b_curve_node.mapping());
294 RGBCurvesNode *curves = graph->create_node<RGBCurvesNode>();
295 array<float3> curve_mapping_curves;
296 float min_x;
297 float max_x;
298 curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, true);
299 curvemapping_minmax(mapping, 4, &min_x, &max_x);
300 curves->set_min_x(min_x);
301 curves->set_max_x(max_x);
302 curves->set_curves(curve_mapping_curves);
303 curves->set_extrapolate(mapping.extend() == BL::CurveMapping::extend_EXTRAPOLATED);
304 node = curves;
305 }
306 if (b_node.is_a(&RNA_ShaderNodeVectorCurve)) {
307 BL::ShaderNodeVectorCurve b_curve_node(b_node);
308 BL::CurveMapping mapping(b_curve_node.mapping());
310 array<float3> curve_mapping_curves;
311 float min_x;
312 float max_x;
313 curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, false);
314 curvemapping_minmax(mapping, 3, &min_x, &max_x);
315 curves->set_min_x(min_x);
316 curves->set_max_x(max_x);
317 curves->set_curves(curve_mapping_curves);
318 curves->set_extrapolate(mapping.extend() == BL::CurveMapping::extend_EXTRAPOLATED);
319 node = curves;
320 }
321 else if (b_node.is_a(&RNA_ShaderNodeFloatCurve)) {
322 BL::ShaderNodeFloatCurve b_curve_node(b_node);
323 BL::CurveMapping mapping(b_curve_node.mapping());
324 FloatCurveNode *curve = graph->create_node<FloatCurveNode>();
325 array<float> curve_mapping_curve;
326 float min_x;
327 float max_x;
328 curvemapping_float_to_array(mapping, curve_mapping_curve, RAMP_TABLE_SIZE);
329 curvemapping_minmax(mapping, 1, &min_x, &max_x);
330 curve->set_min_x(min_x);
331 curve->set_max_x(max_x);
332 curve->set_curve(curve_mapping_curve);
333 curve->set_extrapolate(mapping.extend() == BL::CurveMapping::extend_EXTRAPOLATED);
334 node = curve;
335 }
336 else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) {
337 RGBRampNode *ramp = graph->create_node<RGBRampNode>();
338 BL::ShaderNodeValToRGB b_ramp_node(b_node);
339 BL::ColorRamp b_color_ramp(b_ramp_node.color_ramp());
340 array<float3> ramp_values;
341 array<float> ramp_alpha;
342 colorramp_to_array(b_color_ramp, ramp_values, ramp_alpha, RAMP_TABLE_SIZE);
343 ramp->set_ramp(ramp_values);
344 ramp->set_ramp_alpha(ramp_alpha);
345 ramp->set_interpolate(b_color_ramp.interpolation() != BL::ColorRamp::interpolation_CONSTANT);
346 node = ramp;
347 }
348 else if (b_node.is_a(&RNA_ShaderNodeRGB)) {
349 ColorNode *color = graph->create_node<ColorNode>();
350 color->set_value(get_node_output_rgba(b_node, "Color"));
351 node = color;
352 }
353 else if (b_node.is_a(&RNA_ShaderNodeValue)) {
354 ValueNode *value = graph->create_node<ValueNode>();
355 value->set_value(get_node_output_value(b_node, "Value"));
356 node = value;
357 }
358 else if (b_node.is_a(&RNA_ShaderNodeCameraData)) {
359 node = graph->create_node<CameraNode>();
360 }
361 else if (b_node.is_a(&RNA_ShaderNodeInvert)) {
362 node = graph->create_node<InvertNode>();
363 }
364 else if (b_node.is_a(&RNA_ShaderNodeGamma)) {
365 node = graph->create_node<GammaNode>();
366 }
367 else if (b_node.is_a(&RNA_ShaderNodeBrightContrast)) {
368 node = graph->create_node<BrightContrastNode>();
369 }
370 else if (b_node.is_a(&RNA_ShaderNodeMixRGB)) {
371 BL::ShaderNodeMixRGB b_mix_node(b_node);
372 MixNode *mix = graph->create_node<MixNode>();
373 mix->set_mix_type((NodeMix)b_mix_node.blend_type());
374 mix->set_use_clamp(b_mix_node.use_clamp());
375 node = mix;
376 }
377 else if (b_node.is_a(&RNA_ShaderNodeMix)) {
378 BL::ShaderNodeMix b_mix_node(b_node);
379 if (b_mix_node.data_type() == BL::ShaderNodeMix::data_type_VECTOR) {
380 if (b_mix_node.factor_mode() == BL::ShaderNodeMix::factor_mode_UNIFORM) {
381 MixVectorNode *mix_node = graph->create_node<MixVectorNode>();
382 mix_node->set_use_clamp(b_mix_node.clamp_factor());
383 node = mix_node;
384 }
385 else {
387 mix_node->set_use_clamp(b_mix_node.clamp_factor());
388 node = mix_node;
389 }
390 }
391 else if (b_mix_node.data_type() == BL::ShaderNodeMix::data_type_RGBA) {
392 MixColorNode *mix_node = graph->create_node<MixColorNode>();
393 mix_node->set_blend_type((NodeMix)b_mix_node.blend_type());
394 mix_node->set_use_clamp(b_mix_node.clamp_factor());
395 mix_node->set_use_clamp_result(b_mix_node.clamp_result());
396 node = mix_node;
397 }
398 else {
399 MixFloatNode *mix_node = graph->create_node<MixFloatNode>();
400 mix_node->set_use_clamp(b_mix_node.clamp_factor());
401 node = mix_node;
402 }
403 }
404 else if (b_node.is_a(&RNA_ShaderNodeSeparateColor)) {
405 BL::ShaderNodeSeparateColor b_separate_node(b_node);
406 SeparateColorNode *separate_node = graph->create_node<SeparateColorNode>();
407 separate_node->set_color_type((NodeCombSepColorType)b_separate_node.mode());
408 node = separate_node;
409 }
410 else if (b_node.is_a(&RNA_ShaderNodeCombineColor)) {
411 BL::ShaderNodeCombineColor b_combine_node(b_node);
412 CombineColorNode *combine_node = graph->create_node<CombineColorNode>();
413 combine_node->set_color_type((NodeCombSepColorType)b_combine_node.mode());
414 node = combine_node;
415 }
416 else if (b_node.is_a(&RNA_ShaderNodeSeparateXYZ)) {
417 node = graph->create_node<SeparateXYZNode>();
418 }
419 else if (b_node.is_a(&RNA_ShaderNodeCombineXYZ)) {
420 node = graph->create_node<CombineXYZNode>();
421 }
422 else if (b_node.is_a(&RNA_ShaderNodeHueSaturation)) {
423 node = graph->create_node<HSVNode>();
424 }
425 else if (b_node.is_a(&RNA_ShaderNodeRGBToBW)) {
426 node = graph->create_node<RGBToBWNode>();
427 }
428 else if (b_node.is_a(&RNA_ShaderNodeMapRange)) {
429 BL::ShaderNodeMapRange b_map_range_node(b_node);
430 if (b_map_range_node.data_type() == BL::ShaderNodeMapRange::data_type_FLOAT_VECTOR) {
431 VectorMapRangeNode *vector_map_range_node = graph->create_node<VectorMapRangeNode>();
432 vector_map_range_node->set_use_clamp(b_map_range_node.clamp());
433 vector_map_range_node->set_range_type(
434 (NodeMapRangeType)b_map_range_node.interpolation_type());
435 node = vector_map_range_node;
436 }
437 else {
438 MapRangeNode *map_range_node = graph->create_node<MapRangeNode>();
439 map_range_node->set_clamp(b_map_range_node.clamp());
440 map_range_node->set_range_type((NodeMapRangeType)b_map_range_node.interpolation_type());
441 node = map_range_node;
442 }
443 }
444 else if (b_node.is_a(&RNA_ShaderNodeClamp)) {
445 BL::ShaderNodeClamp b_clamp_node(b_node);
446 ClampNode *clamp_node = graph->create_node<ClampNode>();
447 clamp_node->set_clamp_type((NodeClampType)b_clamp_node.clamp_type());
448 node = clamp_node;
449 }
450 else if (b_node.is_a(&RNA_ShaderNodeMath)) {
451 BL::ShaderNodeMath b_math_node(b_node);
452 MathNode *math_node = graph->create_node<MathNode>();
453 math_node->set_math_type((NodeMathType)b_math_node.operation());
454 math_node->set_use_clamp(b_math_node.use_clamp());
455 node = math_node;
456 }
457 else if (b_node.is_a(&RNA_ShaderNodeVectorMath)) {
458 BL::ShaderNodeVectorMath b_vector_math_node(b_node);
459 VectorMathNode *vector_math_node = graph->create_node<VectorMathNode>();
460 vector_math_node->set_math_type((NodeVectorMathType)b_vector_math_node.operation());
461 node = vector_math_node;
462 }
463 else if (b_node.is_a(&RNA_ShaderNodeVectorRotate)) {
464 BL::ShaderNodeVectorRotate b_vector_rotate_node(b_node);
465 VectorRotateNode *vector_rotate_node = graph->create_node<VectorRotateNode>();
466 vector_rotate_node->set_rotate_type(
467 (NodeVectorRotateType)b_vector_rotate_node.rotation_type());
468 vector_rotate_node->set_invert(b_vector_rotate_node.invert());
469 node = vector_rotate_node;
470 }
471 else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) {
472 BL::ShaderNodeVectorTransform b_vector_transform_node(b_node);
474 vtransform->set_transform_type((NodeVectorTransformType)b_vector_transform_node.vector_type());
475 vtransform->set_convert_from(
476 (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_from());
477 vtransform->set_convert_to(
478 (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_to());
479 node = vtransform;
480 }
481 else if (b_node.is_a(&RNA_ShaderNodeNormal)) {
482 BL::Node::outputs_iterator out_it;
483 b_node.outputs.begin(out_it);
484
486 norm->set_direction(get_node_output_vector(b_node, "Normal"));
487 node = norm;
488 }
489 else if (b_node.is_a(&RNA_ShaderNodeMapping)) {
490 BL::ShaderNodeMapping b_mapping_node(b_node);
491 MappingNode *mapping = graph->create_node<MappingNode>();
492 mapping->set_mapping_type((NodeMappingType)b_mapping_node.vector_type());
493 node = mapping;
494 }
495 else if (b_node.is_a(&RNA_ShaderNodeFresnel)) {
496 node = graph->create_node<FresnelNode>();
497 }
498 else if (b_node.is_a(&RNA_ShaderNodeLayerWeight)) {
499 node = graph->create_node<LayerWeightNode>();
500 }
501 else if (b_node.is_a(&RNA_ShaderNodeAddShader)) {
502 node = graph->create_node<AddClosureNode>();
503 }
504 else if (b_node.is_a(&RNA_ShaderNodeMixShader)) {
505 node = graph->create_node<MixClosureNode>();
506 }
507 else if (b_node.is_a(&RNA_ShaderNodeAttribute)) {
508 BL::ShaderNodeAttribute b_attr_node(b_node);
509 AttributeNode *attr = graph->create_node<AttributeNode>();
510 attr->set_attribute(blender_attribute_name_add_type(b_attr_node.attribute_name(),
511 b_attr_node.attribute_type()));
512 node = attr;
513 }
514 else if (b_node.is_a(&RNA_ShaderNodeBackground)) {
515 node = graph->create_node<BackgroundNode>();
516 }
517 else if (b_node.is_a(&RNA_ShaderNodeHoldout)) {
518 node = graph->create_node<HoldoutNode>();
519 }
520 else if (b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) {
521 node = graph->create_node<DiffuseBsdfNode>();
522 }
523 else if (b_node.is_a(&RNA_ShaderNodeSubsurfaceScattering)) {
524 BL::ShaderNodeSubsurfaceScattering b_subsurface_node(b_node);
525
527
528 switch (b_subsurface_node.falloff()) {
529 case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY:
530 subsurface->set_method(CLOSURE_BSSRDF_BURLEY_ID);
531 break;
532 case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK:
533 subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_ID);
534 break;
535 case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK_SKIN:
536 subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID);
537 break;
538 }
539
540 node = subsurface;
541 }
542 else if (b_node.is_a(&RNA_ShaderNodeBsdfMetallic)) {
543 BL::ShaderNodeBsdfMetallic b_metallic_node(b_node);
545
546 switch (b_metallic_node.distribution()) {
547 case BL::ShaderNodeBsdfMetallic::distribution_BECKMANN:
548 metal->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
549 break;
550 case BL::ShaderNodeBsdfMetallic::distribution_GGX:
551 metal->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID);
552 break;
553 case BL::ShaderNodeBsdfMetallic::distribution_MULTI_GGX:
554 metal->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
555 break;
556 }
557
558 switch (b_metallic_node.fresnel_type()) {
559 case BL::ShaderNodeBsdfMetallic::fresnel_type_PHYSICAL_CONDUCTOR:
560 metal->set_fresnel_type(CLOSURE_BSDF_PHYSICAL_CONDUCTOR);
561 break;
562 case BL::ShaderNodeBsdfMetallic::fresnel_type_F82:
563 metal->set_fresnel_type(CLOSURE_BSDF_F82_CONDUCTOR);
564 break;
565 }
566 node = metal;
567 }
568 else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
569 BL::ShaderNodeBsdfAnisotropic b_glossy_node(b_node);
570 GlossyBsdfNode *glossy = graph->create_node<GlossyBsdfNode>();
571
572 switch (b_glossy_node.distribution()) {
573 case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
574 glossy->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
575 break;
576 case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
577 glossy->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID);
578 break;
579 case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
580 glossy->set_distribution(CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
581 break;
582 case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX:
583 glossy->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
584 break;
585 }
586 node = glossy;
587 }
588 else if (b_node.is_a(&RNA_ShaderNodeBsdfGlass)) {
589 BL::ShaderNodeBsdfGlass b_glass_node(b_node);
590 GlassBsdfNode *glass = graph->create_node<GlassBsdfNode>();
591 switch (b_glass_node.distribution()) {
592 case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
593 glass->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID);
594 break;
595 case BL::ShaderNodeBsdfGlass::distribution_GGX:
596 glass->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
597 break;
598 case BL::ShaderNodeBsdfGlass::distribution_MULTI_GGX:
599 glass->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
600 break;
601 }
602 node = glass;
603 }
604 else if (b_node.is_a(&RNA_ShaderNodeBsdfRefraction)) {
605 BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
606 RefractionBsdfNode *refraction = graph->create_node<RefractionBsdfNode>();
607 switch (b_refraction_node.distribution()) {
608 case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN:
609 refraction->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
610 break;
611 case BL::ShaderNodeBsdfRefraction::distribution_GGX:
612 refraction->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
613 break;
614 }
615 node = refraction;
616 }
617 else if (b_node.is_a(&RNA_ShaderNodeBsdfToon)) {
618 BL::ShaderNodeBsdfToon b_toon_node(b_node);
619 ToonBsdfNode *toon = graph->create_node<ToonBsdfNode>();
620 switch (b_toon_node.component()) {
621 case BL::ShaderNodeBsdfToon::component_DIFFUSE:
622 toon->set_component(CLOSURE_BSDF_DIFFUSE_TOON_ID);
623 break;
624 case BL::ShaderNodeBsdfToon::component_GLOSSY:
625 toon->set_component(CLOSURE_BSDF_GLOSSY_TOON_ID);
626 break;
627 }
628 node = toon;
629 }
630 else if (b_node.is_a(&RNA_ShaderNodeBsdfHair)) {
631 BL::ShaderNodeBsdfHair b_hair_node(b_node);
632 HairBsdfNode *hair = graph->create_node<HairBsdfNode>();
633 switch (b_hair_node.component()) {
634 case BL::ShaderNodeBsdfHair::component_Reflection:
635 hair->set_component(CLOSURE_BSDF_HAIR_REFLECTION_ID);
636 break;
637 case BL::ShaderNodeBsdfHair::component_Transmission:
638 hair->set_component(CLOSURE_BSDF_HAIR_TRANSMISSION_ID);
639 break;
640 }
641 node = hair;
642 }
643 else if (b_node.is_a(&RNA_ShaderNodeBsdfHairPrincipled)) {
644 BL::ShaderNodeBsdfHairPrincipled b_principled_hair_node(b_node);
645 PrincipledHairBsdfNode *principled_hair = graph->create_node<PrincipledHairBsdfNode>();
646 principled_hair->set_model((NodePrincipledHairModel)get_enum(b_principled_hair_node.ptr,
647 "model",
650 principled_hair->set_parametrization(
651 (NodePrincipledHairParametrization)get_enum(b_principled_hair_node.ptr,
652 "parametrization",
655 node = principled_hair;
656 }
657 else if (b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) {
658 BL::ShaderNodeBsdfPrincipled b_principled_node(b_node);
659 PrincipledBsdfNode *principled = graph->create_node<PrincipledBsdfNode>();
660 switch (b_principled_node.distribution()) {
661 case BL::ShaderNodeBsdfPrincipled::distribution_GGX:
662 principled->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
663 break;
664 case BL::ShaderNodeBsdfPrincipled::distribution_MULTI_GGX:
665 principled->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
666 break;
667 }
668 switch (b_principled_node.subsurface_method()) {
669 case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY:
670 principled->set_subsurface_method(CLOSURE_BSSRDF_BURLEY_ID);
671 break;
672 case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK:
673 principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_ID);
674 break;
675 case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK_SKIN:
676 principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID);
677 break;
678 }
679 node = principled;
680 }
681 else if (b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
682 node = graph->create_node<TranslucentBsdfNode>();
683 }
684 else if (b_node.is_a(&RNA_ShaderNodeBsdfTransparent)) {
685 node = graph->create_node<TransparentBsdfNode>();
686 }
687 else if (b_node.is_a(&RNA_ShaderNodeBsdfRayPortal)) {
688 node = graph->create_node<RayPortalBsdfNode>();
689 }
690 else if (b_node.is_a(&RNA_ShaderNodeBsdfSheen)) {
691 BL::ShaderNodeBsdfSheen b_sheen_node(b_node);
693 switch (b_sheen_node.distribution()) {
694 case BL::ShaderNodeBsdfSheen::distribution_ASHIKHMIN:
695 sheen->set_distribution(CLOSURE_BSDF_ASHIKHMIN_VELVET_ID);
696 break;
697 case BL::ShaderNodeBsdfSheen::distribution_MICROFIBER:
698 sheen->set_distribution(CLOSURE_BSDF_SHEEN_ID);
699 break;
700 }
701 node = sheen;
702 }
703 else if (b_node.is_a(&RNA_ShaderNodeEmission)) {
704 node = graph->create_node<EmissionNode>();
705 }
706 else if (b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) {
707 BL::ShaderNodeAmbientOcclusion b_ao_node(b_node);
709 ao->set_samples(b_ao_node.samples());
710 ao->set_inside(b_ao_node.inside());
711 ao->set_only_local(b_ao_node.only_local());
712 node = ao;
713 }
714 else if (b_node.is_a(&RNA_ShaderNodeVolumeScatter)) {
715 BL::ShaderNodeVolumeScatter b_scatter_node(b_node);
717 switch (b_scatter_node.phase()) {
718 case BL::ShaderNodeVolumeScatter::phase_HENYEY_GREENSTEIN:
720 break;
721 case BL::ShaderNodeVolumeScatter::phase_FOURNIER_FORAND:
723 break;
724 case BL::ShaderNodeVolumeScatter::phase_DRAINE:
726 break;
727 case BL::ShaderNodeVolumeScatter::phase_RAYLEIGH:
729 break;
730 case BL::ShaderNodeVolumeScatter::phase_MIE:
731 scatter->set_phase(CLOSURE_VOLUME_MIE_ID);
732 break;
733 }
734 node = scatter;
735 }
736 else if (b_node.is_a(&RNA_ShaderNodeVolumeAbsorption)) {
737 node = graph->create_node<AbsorptionVolumeNode>();
738 }
739 else if (b_node.is_a(&RNA_ShaderNodeVolumeCoefficients)) {
740 BL::ShaderNodeVolumeCoefficients b_coeffs_node(b_node);
742 switch (b_coeffs_node.phase()) {
743 case BL::ShaderNodeVolumeCoefficients::phase_HENYEY_GREENSTEIN:
744 coeffs->set_phase(CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID);
745 break;
746 case BL::ShaderNodeVolumeCoefficients::phase_FOURNIER_FORAND:
747 coeffs->set_phase(CLOSURE_VOLUME_FOURNIER_FORAND_ID);
748 break;
749 case BL::ShaderNodeVolumeCoefficients::phase_DRAINE:
750 coeffs->set_phase(CLOSURE_VOLUME_DRAINE_ID);
751 break;
752 case BL::ShaderNodeVolumeCoefficients::phase_RAYLEIGH:
753 coeffs->set_phase(CLOSURE_VOLUME_RAYLEIGH_ID);
754 break;
755 case BL::ShaderNodeVolumeCoefficients::phase_MIE:
756 coeffs->set_phase(CLOSURE_VOLUME_MIE_ID);
757 break;
758 }
759 node = coeffs;
760 }
761 else if (b_node.is_a(&RNA_ShaderNodeVolumePrincipled)) {
763 node = principled;
764 }
765 else if (b_node.is_a(&RNA_ShaderNodeNewGeometry)) {
766 node = graph->create_node<GeometryNode>();
767 }
768 else if (b_node.is_a(&RNA_ShaderNodeWireframe)) {
769 BL::ShaderNodeWireframe b_wireframe_node(b_node);
770 WireframeNode *wire = graph->create_node<WireframeNode>();
771 wire->set_use_pixel_size(b_wireframe_node.use_pixel_size());
772 node = wire;
773 }
774 else if (b_node.is_a(&RNA_ShaderNodeWavelength)) {
775 node = graph->create_node<WavelengthNode>();
776 }
777 else if (b_node.is_a(&RNA_ShaderNodeBlackbody)) {
778 node = graph->create_node<BlackbodyNode>();
779 }
780 else if (b_node.is_a(&RNA_ShaderNodeLightPath)) {
781 node = graph->create_node<LightPathNode>();
782 }
783 else if (b_node.is_a(&RNA_ShaderNodeLightFalloff)) {
784 node = graph->create_node<LightFalloffNode>();
785 }
786 else if (b_node.is_a(&RNA_ShaderNodeObjectInfo)) {
787 node = graph->create_node<ObjectInfoNode>();
788 }
789 else if (b_node.is_a(&RNA_ShaderNodeParticleInfo)) {
790 node = graph->create_node<ParticleInfoNode>();
791 }
792 else if (b_node.is_a(&RNA_ShaderNodeHairInfo)) {
793 node = graph->create_node<HairInfoNode>();
794 }
795 else if (b_node.is_a(&RNA_ShaderNodePointInfo)) {
796 node = graph->create_node<PointInfoNode>();
797 }
798 else if (b_node.is_a(&RNA_ShaderNodeVolumeInfo)) {
799 node = graph->create_node<VolumeInfoNode>();
800 }
801 else if (b_node.is_a(&RNA_ShaderNodeVertexColor)) {
802 BL::ShaderNodeVertexColor b_vertex_color_node(b_node);
803 VertexColorNode *vertex_color_node = graph->create_node<VertexColorNode>();
804 vertex_color_node->set_layer_name(ustring(b_vertex_color_node.layer_name()));
805 node = vertex_color_node;
806 }
807 else if (b_node.is_a(&RNA_ShaderNodeBump)) {
808 BL::ShaderNodeBump b_bump_node(b_node);
809 BumpNode *bump = graph->create_node<BumpNode>();
810 bump->set_invert(b_bump_node.invert());
811 node = bump;
812 }
813 else if (b_node.is_a(&RNA_ShaderNodeScript)) {
814#ifdef WITH_OSL
815 if (scene->shader_manager->use_osl()) {
816 /* create script node */
817 BL::ShaderNodeScript b_script_node(b_node);
818
819 const string bytecode_hash = b_script_node.bytecode_hash();
820 if (!bytecode_hash.empty()) {
821 node = OSLShaderManager::osl_node(
822 graph, scene, "", bytecode_hash, b_script_node.bytecode());
823 }
824 else {
825 const string absolute_filepath = blender_absolute_path(
826 b_data, b_ntree, b_script_node.filepath());
827 node = OSLShaderManager::osl_node(graph, scene, absolute_filepath, "");
828 }
829 }
830#else
831 (void)b_data;
832 (void)b_ntree;
833#endif
834 }
835 else if (b_node.is_a(&RNA_ShaderNodeTexImage)) {
836 BL::ShaderNodeTexImage b_image_node(b_node);
837 BL::Image b_image(b_image_node.image());
838 BL::ImageUser b_image_user(b_image_node.image_user());
840
841 image->set_interpolation(get_image_interpolation(b_image_node));
842 image->set_extension(get_image_extension(b_image_node));
843 image->set_projection((NodeImageProjection)b_image_node.projection());
844 image->set_projection_blend(b_image_node.projection_blend());
845 BL::TexMapping b_texture_mapping(b_image_node.texture_mapping());
846 get_tex_mapping(image, b_texture_mapping);
847
848 if (b_image) {
849 const BL::Image::source_enum b_image_source = b_image.source();
850 PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
851 image->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name")));
852
853 image->set_animated(is_image_animated(b_image_source, b_image_user));
854 image->set_alpha_type(get_image_alpha_type(b_image));
855
856 if (b_image_source == BL::Image::source_TILED) {
858 for (BL::UDIMTile &b_tile : b_image.tiles) {
859 tiles.push_back_slow(b_tile.number());
860 }
861 image->set_tiles(tiles);
862 }
863
864 /* builtin images will use callback-based reading because
865 * they could only be loaded correct from blender side
866 */
867 const bool is_builtin = image_is_builtin(b_image, b_engine);
868
869 if (is_builtin) {
870 /* for builtin images we're using image datablock name to find an image to
871 * read pixels from later
872 *
873 * also store frame number as well, so there's no differences in handling
874 * builtin names for packed images and movies
875 */
876 const int scene_frame = b_scene.frame_current();
877 const int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
878 if (b_image_source != BL::Image::source_TILED) {
879 image->handle = scene->image_manager->add_image(
880 make_unique<BlenderImageLoader>(static_cast<::Image *>(b_image.ptr.data),
881 static_cast<::ImageUser *>(b_image_user.ptr.data),
882 image_frame,
883 0,
884 b_engine.is_preview()),
885 image->image_params());
886 }
887 else {
889 loaders.reserve(image->get_tiles().size());
890 for (const int tile_number : image->get_tiles()) {
891 loaders.push_back(
892 make_unique<BlenderImageLoader>(static_cast<::Image *>(b_image.ptr.data),
893 static_cast<::ImageUser *>(b_image_user.ptr.data),
894 image_frame,
895 tile_number,
896 b_engine.is_preview()));
897 }
898
899 image->handle = scene->image_manager->add_image(std::move(loaders),
900 image->image_params());
901 }
902 }
903 else {
904 const ustring filename = ustring(
905 image_user_file_path(b_data, b_image_user, b_image, b_scene.frame_current()));
906 image->set_filename(filename);
907 }
908 }
909 node = image;
910 }
911 else if (b_node.is_a(&RNA_ShaderNodeTexEnvironment)) {
912 BL::ShaderNodeTexEnvironment b_env_node(b_node);
913 BL::Image b_image(b_env_node.image());
914 BL::ImageUser b_image_user(b_env_node.image_user());
916
917 env->set_interpolation(get_image_interpolation(b_env_node));
918 env->set_projection((NodeEnvironmentProjection)b_env_node.projection());
919 BL::TexMapping b_texture_mapping(b_env_node.texture_mapping());
920 get_tex_mapping(env, b_texture_mapping);
921
922 if (b_image) {
923 const BL::Image::source_enum b_image_source = b_image.source();
924 PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
925 env->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name")));
926 env->set_animated(is_image_animated(b_image_source, b_image_user));
927 env->set_alpha_type(get_image_alpha_type(b_image));
928
929 const bool is_builtin = image_is_builtin(b_image, b_engine);
930
931 if (is_builtin) {
932 const int scene_frame = b_scene.frame_current();
933 const int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
934 env->handle = scene->image_manager->add_image(
935 make_unique<BlenderImageLoader>(static_cast<::Image *>(b_image.ptr.data),
936 static_cast<::ImageUser *>(b_image_user.ptr.data),
937 image_frame,
938 0,
939 b_engine.is_preview()),
940 env->image_params());
941 }
942 else {
943 env->set_filename(
944 ustring(image_user_file_path(b_data, b_image_user, b_image, b_scene.frame_current())));
945 }
946 }
947 node = env;
948 }
949 else if (b_node.is_a(&RNA_ShaderNodeTexGradient)) {
950 BL::ShaderNodeTexGradient b_gradient_node(b_node);
952 gradient->set_gradient_type((NodeGradientType)b_gradient_node.gradient_type());
953 BL::TexMapping b_texture_mapping(b_gradient_node.texture_mapping());
954 get_tex_mapping(gradient, b_texture_mapping);
955 node = gradient;
956 }
957 else if (b_node.is_a(&RNA_ShaderNodeTexVoronoi)) {
958 BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
960 voronoi->set_dimensions(b_voronoi_node.voronoi_dimensions());
961 voronoi->set_feature((NodeVoronoiFeature)b_voronoi_node.feature());
962 voronoi->set_metric((NodeVoronoiDistanceMetric)b_voronoi_node.distance());
963 voronoi->set_use_normalize(b_voronoi_node.normalize());
964 BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping());
965 get_tex_mapping(voronoi, b_texture_mapping);
966 node = voronoi;
967 }
968 else if (b_node.is_a(&RNA_ShaderNodeTexMagic)) {
969 BL::ShaderNodeTexMagic b_magic_node(b_node);
971 magic->set_depth(b_magic_node.turbulence_depth());
972 BL::TexMapping b_texture_mapping(b_magic_node.texture_mapping());
973 get_tex_mapping(magic, b_texture_mapping);
974 node = magic;
975 }
976 else if (b_node.is_a(&RNA_ShaderNodeTexWave)) {
977 BL::ShaderNodeTexWave b_wave_node(b_node);
979 wave->set_wave_type((NodeWaveType)b_wave_node.wave_type());
980 wave->set_bands_direction((NodeWaveBandsDirection)b_wave_node.bands_direction());
981 wave->set_rings_direction((NodeWaveRingsDirection)b_wave_node.rings_direction());
982 wave->set_profile((NodeWaveProfile)b_wave_node.wave_profile());
983 BL::TexMapping b_texture_mapping(b_wave_node.texture_mapping());
984 get_tex_mapping(wave, b_texture_mapping);
985 node = wave;
986 }
987 else if (b_node.is_a(&RNA_ShaderNodeTexChecker)) {
988 BL::ShaderNodeTexChecker b_checker_node(b_node);
990 BL::TexMapping b_texture_mapping(b_checker_node.texture_mapping());
991 get_tex_mapping(checker, b_texture_mapping);
992 node = checker;
993 }
994 else if (b_node.is_a(&RNA_ShaderNodeTexBrick)) {
995 BL::ShaderNodeTexBrick b_brick_node(b_node);
997 brick->set_offset(b_brick_node.offset());
998 brick->set_offset_frequency(b_brick_node.offset_frequency());
999 brick->set_squash(b_brick_node.squash());
1000 brick->set_squash_frequency(b_brick_node.squash_frequency());
1001 BL::TexMapping b_texture_mapping(b_brick_node.texture_mapping());
1002 get_tex_mapping(brick, b_texture_mapping);
1003 node = brick;
1004 }
1005 else if (b_node.is_a(&RNA_ShaderNodeTexNoise)) {
1006 BL::ShaderNodeTexNoise b_noise_node(b_node);
1008 noise->set_dimensions(b_noise_node.noise_dimensions());
1009 noise->set_type((NodeNoiseType)b_noise_node.noise_type());
1010 noise->set_use_normalize(b_noise_node.normalize());
1011 BL::TexMapping b_texture_mapping(b_noise_node.texture_mapping());
1012 get_tex_mapping(noise, b_texture_mapping);
1013 node = noise;
1014 }
1015 else if (b_node.is_a(&RNA_ShaderNodeTexGabor)) {
1016 BL::ShaderNodeTexGabor b_gabor_node(b_node);
1018 gabor->set_type((NodeGaborType)b_gabor_node.gabor_type());
1019 BL::TexMapping b_texture_mapping(b_gabor_node.texture_mapping());
1020 get_tex_mapping(gabor, b_texture_mapping);
1021 node = gabor;
1022 }
1023 else if (b_node.is_a(&RNA_ShaderNodeTexCoord)) {
1024 BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
1026 tex_coord->set_from_dupli(b_tex_coord_node.from_instancer());
1027 if (b_tex_coord_node.object()) {
1028 tex_coord->set_use_transform(true);
1029 tex_coord->set_ob_tfm(get_transform(b_tex_coord_node.object().matrix_world()));
1030 }
1031 node = tex_coord;
1032 }
1033 else if (b_node.is_a(&RNA_ShaderNodeTexSky)) {
1034 BL::ShaderNodeTexSky b_sky_node(b_node);
1035 SkyTextureNode *sky = graph->create_node<SkyTextureNode>();
1036 sky->set_sky_type((NodeSkyType)b_sky_node.sky_type());
1037 sky->set_sun_direction(normalize(get_float3(b_sky_node.sun_direction())));
1038 sky->set_turbidity(b_sky_node.turbidity());
1039 sky->set_ground_albedo(b_sky_node.ground_albedo());
1040 sky->set_sun_disc(b_sky_node.sun_disc());
1041 sky->set_sun_size(b_sky_node.sun_size());
1042 sky->set_sun_intensity(b_sky_node.sun_intensity());
1043 sky->set_sun_elevation(b_sky_node.sun_elevation());
1044 sky->set_sun_rotation(b_sky_node.sun_rotation());
1045 sky->set_altitude(b_sky_node.altitude());
1046 sky->set_air_density(b_sky_node.air_density());
1047 sky->set_aerosol_density(b_sky_node.aerosol_density());
1048 sky->set_ozone_density(b_sky_node.ozone_density());
1049 BL::TexMapping b_texture_mapping(b_sky_node.texture_mapping());
1050 get_tex_mapping(sky, b_texture_mapping);
1051 node = sky;
1052 }
1053 else if (b_node.is_a(&RNA_ShaderNodeTexIES)) {
1054 BL::ShaderNodeTexIES b_ies_node(b_node);
1055 IESLightNode *ies = graph->create_node<IESLightNode>();
1056 switch (b_ies_node.mode()) {
1057 case BL::ShaderNodeTexIES::mode_EXTERNAL:
1058 ies->set_filename(ustring(blender_absolute_path(b_data, b_ntree, b_ies_node.filepath())));
1059 break;
1060 case BL::ShaderNodeTexIES::mode_INTERNAL:
1061 ustring ies_content = ustring(get_text_datablock_content(b_ies_node.ies().ptr));
1062 if (ies_content.empty()) {
1063 ies_content = "\n";
1064 }
1065 ies->set_ies(ies_content);
1066 break;
1067 }
1068 node = ies;
1069 }
1070 else if (b_node.is_a(&RNA_ShaderNodeTexWhiteNoise)) {
1071 BL::ShaderNodeTexWhiteNoise b_tex_white_noise_node(b_node);
1072 WhiteNoiseTextureNode *white_noise_node = graph->create_node<WhiteNoiseTextureNode>();
1073 white_noise_node->set_dimensions(b_tex_white_noise_node.noise_dimensions());
1074 node = white_noise_node;
1075 }
1076 else if (b_node.is_a(&RNA_ShaderNodeNormalMap)) {
1077 BL::ShaderNodeNormalMap b_normal_map_node(b_node);
1078 NormalMapNode *nmap = graph->create_node<NormalMapNode>();
1079 nmap->set_space((NodeNormalMapSpace)b_normal_map_node.space());
1080 nmap->set_attribute(ustring(b_normal_map_node.uv_map()));
1081 node = nmap;
1082 }
1083 else if (b_node.is_a(&RNA_ShaderNodeRadialTiling)) {
1084 BL::ShaderNodeRadialTiling b_radial_tiling_node(b_node);
1085 RadialTilingNode *radial_tiling = graph->create_node<RadialTilingNode>();
1086 radial_tiling->set_use_normalize(b_radial_tiling_node.normalize());
1087 node = radial_tiling;
1088 }
1089 else if (b_node.is_a(&RNA_ShaderNodeTangent)) {
1090 BL::ShaderNodeTangent b_tangent_node(b_node);
1091 TangentNode *tangent = graph->create_node<TangentNode>();
1092 tangent->set_direction_type((NodeTangentDirectionType)b_tangent_node.direction_type());
1093 tangent->set_axis((NodeTangentAxis)b_tangent_node.axis());
1094 tangent->set_attribute(ustring(b_tangent_node.uv_map()));
1095 node = tangent;
1096 }
1097 else if (b_node.is_a(&RNA_ShaderNodeUVMap)) {
1098 BL::ShaderNodeUVMap b_uvmap_node(b_node);
1099 UVMapNode *uvm = graph->create_node<UVMapNode>();
1100 uvm->set_attribute(ustring(b_uvmap_node.uv_map()));
1101 uvm->set_from_dupli(b_uvmap_node.from_instancer());
1102 node = uvm;
1103 }
1104 else if (b_node.is_a(&RNA_ShaderNodeBevel)) {
1105 BL::ShaderNodeBevel b_bevel_node(b_node);
1106 BevelNode *bevel = graph->create_node<BevelNode>();
1107 bevel->set_samples(b_bevel_node.samples());
1108 node = bevel;
1109 }
1110 else if (b_node.is_a(&RNA_ShaderNodeDisplacement)) {
1111 BL::ShaderNodeDisplacement b_disp_node(b_node);
1113 disp->set_space((NodeNormalMapSpace)b_disp_node.space());
1114 node = disp;
1115 }
1116 else if (b_node.is_a(&RNA_ShaderNodeVectorDisplacement)) {
1117 BL::ShaderNodeVectorDisplacement b_disp_node(b_node);
1119 disp->set_space((NodeNormalMapSpace)b_disp_node.space());
1120 disp->set_attribute(ustring(""));
1121 node = disp;
1122 }
1123 else if (b_node.is_a(&RNA_ShaderNodeOutputAOV)) {
1124 BL::ShaderNodeOutputAOV b_aov_node(b_node);
1125 OutputAOVNode *aov = graph->create_node<OutputAOVNode>();
1126 aov->set_name(ustring(b_aov_node.aov_name()));
1127 node = aov;
1128 }
1129
1130 if (node) {
1131 node->name = b_node.name();
1132 }
1133
1134 return node;
1135}
1136
1138{
1140 return false;
1141 }
1142
1143 return true;
1144}
1145
1146static ShaderInput *node_find_input_by_name(BL::Node b_node,
1147 ShaderNode *node,
1148 BL::NodeSocket &b_socket)
1149{
1150 string name = b_socket.identifier();
1151 ShaderInput *input = node->input(name.c_str());
1152
1153 if (!input && node_use_modified_socket_name(node)) {
1154 /* Different internal name for shader. */
1155 if (string_startswith(name, "Shader")) {
1156 string_replace(name, "Shader", "Closure");
1157 }
1158
1159 /* Map mix node internal name for shader. */
1160 if (b_node.is_a(&RNA_ShaderNodeMix)) {
1161 if (string_endswith(name, "Factor_Float")) {
1162 string_replace(name, "Factor_Float", "Factor");
1163 }
1164 else if (string_endswith(name, "Factor_Vector")) {
1165 string_replace(name, "Factor_Vector", "Factor");
1166 }
1167 else if (string_endswith(name, "A_Float")) {
1168 string_replace(name, "A_Float", "A");
1169 }
1170 else if (string_endswith(name, "B_Float")) {
1171 string_replace(name, "B_Float", "B");
1172 }
1173 else if (string_endswith(name, "A_Color")) {
1174 string_replace(name, "A_Color", "A");
1175 }
1176 else if (string_endswith(name, "B_Color")) {
1177 string_replace(name, "B_Color", "B");
1178 }
1179 else if (string_endswith(name, "A_Vector")) {
1180 string_replace(name, "A_Vector", "A");
1181 }
1182 else if (string_endswith(name, "B_Vector")) {
1183 string_replace(name, "B_Vector", "B");
1184 }
1185 }
1186
1187 input = node->input(name.c_str());
1188
1189 if (!input) {
1190 /* Different internal numbering of two sockets with same name.
1191 * Note that the Blender convention for unique socket names changed
1192 * from . to _ at some point, so we check both to handle old files. */
1193 if (string_endswith(name, "_001")) {
1194 string_replace(name, "_001", "2");
1195 }
1196 else if (string_endswith(name, ".001")) {
1197 string_replace(name, ".001", "2");
1198 }
1199 else if (string_endswith(name, "_002")) {
1200 string_replace(name, "_002", "3");
1201 }
1202 else if (string_endswith(name, ".002")) {
1203 string_replace(name, ".002", "3");
1204 }
1205 else {
1206 name += "1";
1207 }
1208
1209 input = node->input(name.c_str());
1210 }
1211 }
1212
1213 return input;
1214}
1215
1217 ShaderNode *node,
1218 BL::NodeSocket &b_socket)
1219{
1220 string name = b_socket.identifier();
1221 ShaderOutput *output = node->output(name.c_str());
1222
1223 if (!output && node_use_modified_socket_name(node)) {
1224 /* Different internal name for shader. */
1225 if (name == "Shader") {
1226 name = "Closure";
1227 output = node->output(name.c_str());
1228 }
1229 /* Map internal name for shader. */
1230 if (b_node.is_a(&RNA_ShaderNodeMix)) {
1231 if (string_endswith(name, "Result_Float")) {
1232 string_replace(name, "Result_Float", "Result");
1233 output = node->output(name.c_str());
1234 }
1235 else if (string_endswith(name, "Result_Color")) {
1236 string_replace(name, "Result_Color", "Result");
1237 output = node->output(name.c_str());
1238 }
1239 else if (string_endswith(name, "Result_Vector")) {
1240 string_replace(name, "Result_Vector", "Result");
1241 output = node->output(name.c_str());
1242 }
1243 }
1244 }
1245
1246 return output;
1247}
1248
1249static void add_nodes(Scene *scene,
1250 BL::RenderEngine &b_engine,
1251 BL::BlendData &b_data,
1252 BL::Scene &b_scene,
1253 ShaderGraph *graph,
1254 BL::ShaderNodeTree &b_ntree,
1255 const ProxyMap &proxy_input_map,
1256 const ProxyMap &proxy_output_map);
1257
1258static void add_nodes_inlined(Scene *scene,
1259 BL::RenderEngine &b_engine,
1260 BL::BlendData &b_data,
1261 BL::Scene &b_scene,
1262 ShaderGraph *graph,
1263 BL::ShaderNodeTree &b_ntree,
1264 const ProxyMap &proxy_input_map,
1265 const ProxyMap &proxy_output_map)
1266{
1267 /* add nodes */
1268 PtrInputMap input_map;
1269 PtrOutputMap output_map;
1270
1271 /* find the node to use for output if there are multiple */
1272 const BL::ShaderNode output_node = b_ntree.get_output_node(
1273 BL::ShaderNodeOutputMaterial::target_CYCLES);
1274
1275 /* add nodes */
1276 for (BL::Node &b_node : b_ntree.nodes) {
1277 if (b_node.mute() || b_node.is_a(&RNA_NodeReroute)) {
1278 /* replace muted node with internal links */
1279 for (BL::NodeLink &b_link : b_node.internal_links) {
1280 BL::NodeSocket to_socket(b_link.to_socket());
1281 const SocketType::Type to_socket_type = convert_socket_type(to_socket);
1282 if (to_socket_type == SocketType::UNDEFINED) {
1283 continue;
1284 }
1285
1286 ConvertNode *proxy = graph->create_node<ConvertNode>(to_socket_type, to_socket_type, true);
1287
1288 /* Muted nodes can result in multiple Cycles input sockets mapping to the same Blender
1289 * input socket, so this needs to be a multimap. */
1290 input_map.emplace(b_link.from_socket().ptr.data, proxy->inputs[0]);
1291 output_map[b_link.to_socket().ptr.data] = proxy->outputs[0];
1292 }
1293 }
1294 else if (b_node.is_a(&RNA_ShaderNodeGroup) || b_node.is_a(&RNA_NodeCustomGroup) ||
1295 b_node.is_a(&RNA_ShaderNodeCustomGroup))
1296 {
1297
1298 BL::ShaderNodeTree b_group_ntree(PointerRNA_NULL);
1299 if (b_node.is_a(&RNA_ShaderNodeGroup)) {
1300 b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(b_node)).node_tree());
1301 }
1302 else if (b_node.is_a(&RNA_NodeCustomGroup)) {
1303 b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(b_node)).node_tree());
1304 }
1305 else {
1306 b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(b_node)).node_tree());
1307 }
1308
1309 ProxyMap group_proxy_input_map;
1310 ProxyMap group_proxy_output_map;
1311
1312 /* Add a proxy node for each socket
1313 * Do this even if the node group has no internal tree,
1314 * so that links have something to connect to and assert won't fail.
1315 */
1316 for (BL::NodeSocket &b_input : b_node.inputs) {
1317 const SocketType::Type input_type = convert_socket_type(b_input);
1318 if (input_type == SocketType::UNDEFINED) {
1319 continue;
1320 }
1321
1322 ConvertNode *proxy = graph->create_node<ConvertNode>(input_type, input_type, true);
1323
1324 /* register the proxy node for internal binding */
1325 group_proxy_input_map[b_input.identifier()] = proxy;
1326
1327 input_map.emplace(b_input.ptr.data, proxy->inputs[0]);
1328
1329 set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
1330 }
1331 for (BL::NodeSocket &b_output : b_node.outputs) {
1332 const SocketType::Type output_type = convert_socket_type(b_output);
1333 if (output_type == SocketType::UNDEFINED) {
1334 continue;
1335 }
1336
1337 ConvertNode *proxy = graph->create_node<ConvertNode>(output_type, output_type, true);
1338
1339 /* register the proxy node for internal binding */
1340 group_proxy_output_map[b_output.identifier()] = proxy;
1341
1342 output_map[b_output.ptr.data] = proxy->outputs[0];
1343 }
1344
1345 if (b_group_ntree) {
1346 add_nodes(scene,
1347 b_engine,
1348 b_data,
1349 b_scene,
1350 graph,
1351 b_group_ntree,
1352 group_proxy_input_map,
1353 group_proxy_output_map);
1354 }
1355 }
1356 else if (b_node.is_a(&RNA_NodeGroupInput)) {
1357 /* map each socket to a proxy node */
1358 for (BL::NodeSocket &b_output : b_node.outputs) {
1359 const ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output.identifier());
1360 if (proxy_it != proxy_input_map.end()) {
1361 ConvertNode *proxy = proxy_it->second;
1362
1363 output_map[b_output.ptr.data] = proxy->outputs[0];
1364 }
1365 }
1366 }
1367 else if (b_node.is_a(&RNA_NodeGroupOutput)) {
1368 BL::NodeGroupOutput b_output_node(b_node);
1369 /* only the active group output is used */
1370 if (b_output_node.is_active_output()) {
1371 /* map each socket to a proxy node */
1372 for (BL::NodeSocket &b_input : b_node.inputs) {
1373 const ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input.identifier());
1374 if (proxy_it != proxy_output_map.end()) {
1375 ConvertNode *proxy = proxy_it->second;
1376
1377 input_map.emplace(b_input.ptr.data, proxy->inputs[0]);
1378
1379 set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
1380 }
1381 }
1382 }
1383 }
1384 /* TODO: All the previous cases can be removed? */
1385 else {
1386 ShaderNode *node = nullptr;
1387
1388 if (b_node.ptr.data == output_node.ptr.data) {
1389 node = graph->output();
1390 }
1391 else {
1392 BL::ShaderNode b_shader_node(b_node);
1393 node = add_node(scene, b_engine, b_data, b_scene, graph, b_ntree, b_shader_node);
1394 }
1395
1396 if (node) {
1397 /* map node sockets for linking */
1398 for (BL::NodeSocket &b_input : b_node.inputs) {
1399 if (b_input.is_unavailable()) {
1400 /* Skip unavailable sockets. */
1401 continue;
1402 }
1403 ShaderInput *input = node_find_input_by_name(b_node, node, b_input);
1404 if (!input) {
1405 /* XXX should not happen, report error? */
1406 continue;
1407 }
1408 input_map.emplace(b_input.ptr.data, input);
1409
1410 set_default_value(input, b_input, b_data, b_ntree);
1411 }
1412 for (BL::NodeSocket &b_output : b_node.outputs) {
1413 if (b_output.is_unavailable()) {
1414 /* Skip unavailable sockets. */
1415 continue;
1416 }
1417 ShaderOutput *output = node_find_output_by_name(b_node, node, b_output);
1418 if (!output) {
1419 /* XXX should not happen, report error? */
1420 continue;
1421 }
1422 output_map[b_output.ptr.data] = output;
1423 }
1424 }
1425 }
1426 }
1427
1428 /* connect nodes */
1429 for (BL::NodeLink &b_link : b_ntree.links) {
1430 /* Ignore invalid links to avoid unwanted cycles created in graph.
1431 * Also ignore links with unavailable sockets. */
1432 if (!(b_link.is_valid() && b_link.from_socket().enabled() && b_link.to_socket().enabled()) ||
1433 b_link.is_muted())
1434 {
1435 continue;
1436 }
1437 /* get blender link data */
1438 const BL::NodeSocket b_from_sock = b_link.from_socket();
1439 const BL::NodeSocket b_to_sock = b_link.to_socket();
1440
1441 ShaderOutput *output = nullptr;
1442 const PtrOutputMap::iterator output_it = output_map.find(b_from_sock.ptr.data);
1443 if (output_it != output_map.end()) {
1444 output = output_it->second;
1445 }
1446
1447 /* either socket may be nullptr when the node was not exported, typically
1448 * because the node type is not supported */
1449 if (output != nullptr) {
1450 ShaderOutput *output = output_it->second;
1451 auto inputs = input_map.equal_range(b_to_sock.ptr.data);
1452 for (PtrInputMap::iterator input_it = inputs.first; input_it != inputs.second; ++input_it) {
1453 ShaderInput *input = input_it->second;
1454 if (input != nullptr) {
1455 graph->connect(output, input);
1456 }
1457 }
1458 }
1459 }
1460}
1461
1462static void add_nodes(Scene *scene,
1463 BL::RenderEngine &b_engine,
1464 BL::BlendData &b_data,
1465 BL::Scene &b_scene,
1466 ShaderGraph *graph,
1467 BL::ShaderNodeTree &b_ntree,
1468 const ProxyMap &proxy_input_map,
1469 const ProxyMap &proxy_output_map)
1470{
1471 bNodeTree *ntree = b_ntree.ptr.data_as<bNodeTree>();
1473 nullptr, (blender::StringRef(ntree->id.name) + " Inlined").c_str(), ntree->idname);
1475 inline_params.allow_preserving_repeat_zones = false;
1476 blender::nodes::inline_shader_node_tree(*ntree, *localtree, inline_params);
1477
1478 BL::ShaderNodeTree b_localtree(RNA_id_pointer_create(&localtree->id));
1480 scene, b_engine, b_data, b_scene, graph, b_localtree, proxy_input_map, proxy_output_map);
1481
1482 BKE_id_free(nullptr, &localtree->id);
1483}
1484
1485static void add_nodes(Scene *scene,
1486 BL::RenderEngine &b_engine,
1487 BL::BlendData &b_data,
1488 BL::Scene &b_scene,
1489 ShaderGraph *graph,
1490 BL::ShaderNodeTree &b_ntree)
1491{
1492 static const ProxyMap empty_proxy_map;
1493 add_nodes(scene, b_engine, b_data, b_scene, graph, b_ntree, empty_proxy_map, empty_proxy_map);
1494}
1495
1496/* Look up and constant fold all references to View Layer attributes. */
1497void BlenderSync::resolve_view_layer_attributes(Shader *shader,
1498 ShaderGraph *graph,
1499 BL::Depsgraph &b_depsgraph)
1500{
1501 bool updated = false;
1502
1503 for (ShaderNode *node : graph->nodes) {
1504 if (node->is_a(AttributeNode::get_node_type())) {
1505 AttributeNode *attr_node = static_cast<AttributeNode *>(node);
1506
1507 std::string real_name;
1509 attr_node->get_attribute(), &real_name);
1510
1511 if (type == BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER) {
1512 /* Look up the value. */
1513 const BL::ViewLayer b_layer = b_depsgraph.view_layer_eval();
1514 const BL::Scene b_scene = b_depsgraph.scene_eval();
1515 float4 value;
1516
1517 BKE_view_layer_find_rgba_attribute((::Scene *)b_scene.ptr.data,
1518 (::ViewLayer *)b_layer.ptr.data,
1519 real_name.c_str(),
1520 &value.x);
1521
1522 /* Replace all outgoing links, using appropriate output types. */
1523 const float val_avg = (value.x + value.y + value.z) / 3.0f;
1524
1525 for (ShaderOutput *output : node->outputs) {
1526 float val_float;
1527 float3 val_float3;
1528
1529 if (output->type() == SocketType::FLOAT) {
1530 val_float = (output->name() == "Alpha") ? value.w : val_avg;
1531 val_float3 = make_float3(val_float);
1532 }
1533 else {
1534 val_float = val_avg;
1535 val_float3 = make_float3(value);
1536 }
1537
1538 for (ShaderInput *sock : output->links) {
1539 if (sock->type() == SocketType::FLOAT) {
1540 sock->set(val_float);
1541 }
1542 else if (SocketType::is_float3(sock->type())) {
1543 sock->set(val_float3);
1544 }
1545
1546 sock->constant_folded_in = true;
1547 }
1548
1549 graph->disconnect(output);
1550 }
1551
1552 /* Clear the attribute name to avoid further attempts to look up. */
1553 attr_node->set_attribute(ustring());
1554 updated = true;
1555 }
1556 }
1557 }
1558
1559 if (updated) {
1560 shader_map.set_flag(shader, SHADER_WITH_LAYER_ATTRS);
1561 }
1562 else {
1563 shader_map.clear_flag(shader, SHADER_WITH_LAYER_ATTRS);
1564 }
1565}
1566
1567bool BlenderSync::scene_attr_needs_recalc(Shader *shader, BL::Depsgraph &b_depsgraph)
1568{
1569 if (shader && shader_map.test_flag(shader, SHADER_WITH_LAYER_ATTRS)) {
1570 BL::Scene scene = b_depsgraph.scene_eval();
1571
1572 return shader_map.check_recalc(scene) || shader_map.check_recalc(scene.world()) ||
1573 shader_map.check_recalc(scene.camera());
1574 }
1575
1576 return false;
1577}
1578
1579/* Sync Materials */
1580
1581void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
1582{
1583 shader_map.set_default(scene->default_surface);
1584
1585 TaskPool pool;
1586 set<Shader *> updated_shaders;
1587
1588 for (BL::ID &b_id : b_depsgraph.ids) {
1589 if (!b_id.is_a(&RNA_Material)) {
1590 continue;
1591 }
1592
1593 BL::Material b_mat(b_id);
1594 Shader *shader;
1595
1596 /* test if we need to sync */
1597 if (shader_map.add_or_update(&shader, b_mat) || update_all ||
1598 scene_attr_needs_recalc(shader, b_depsgraph))
1599 {
1600 unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
1601
1602 shader->name = b_mat.name().c_str();
1603 shader->set_pass_id(b_mat.pass_index());
1604
1605 /* create nodes */
1606 if (b_mat.node_tree()) {
1607 BL::ShaderNodeTree b_ntree(b_mat.node_tree());
1608
1609 add_nodes(scene, b_engine, b_data, b_scene, graph.get(), b_ntree);
1610 }
1611 else {
1612 DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>();
1613 diffuse->set_color(get_float3(b_mat.diffuse_color()));
1614
1615 ShaderNode *out = graph->output();
1616 graph->connect(diffuse->output("BSDF"), out->input("Surface"));
1617 }
1618
1619 resolve_view_layer_attributes(shader, graph.get(), b_depsgraph);
1620
1621 /* settings */
1622 PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
1623 shader->set_emission_sampling_method(get_emission_sampling(cmat));
1624 shader->set_use_transparent_shadow(b_mat.use_transparent_shadow());
1625 shader->set_use_bump_map_correction(get_boolean(cmat, "use_bump_map_correction"));
1626 shader->set_volume_sampling_method(get_volume_sampling(cmat));
1627 shader->set_volume_interpolation_method(get_volume_interpolation(cmat));
1628 shader->set_volume_step_rate(get_float(cmat, "volume_step_rate"));
1629 shader->set_displacement_method(get_displacement_method(b_mat));
1630
1631 shader->set_graph(std::move(graph));
1632
1633 /* By simplifying the shader graph as soon as possible, some
1634 * redundant shader nodes might be removed which prevents loading
1635 * unnecessary attributes later.
1636 *
1637 * However, since graph simplification also accounts for mix
1638 * weight, this would cause frequent expensive resyncs in interactive
1639 * sessions, so for those sessions optimization is only performed
1640 * right before compiling.
1641 */
1642 if (!preview) {
1643 pool.push([graph = shader->graph.get(), scene = scene] { graph->simplify(scene); });
1644 /* NOTE: Update shaders out of the threads since those routines
1645 * are accessing and writing to a global context.
1646 */
1647 updated_shaders.insert(shader);
1648 }
1649 else {
1650 /* NOTE: Update tagging can access links which are being
1651 * optimized out.
1652 */
1653 shader->tag_update(scene);
1654 }
1655 }
1656 }
1657
1658 pool.wait_work();
1659
1660 for (Shader *shader : updated_shaders) {
1661 shader->tag_update(scene);
1662 }
1663}
1664
1665/* Sync World */
1666
1667void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all)
1668{
1669 Background *background = scene->background;
1670 Integrator *integrator = scene->integrator;
1671 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
1672
1673 BL::World b_world = view_layer.world_override ? view_layer.world_override : b_scene.world();
1674
1675 const BlenderViewportParameters new_viewport_parameters(b_v3d, use_developer_ui);
1676
1677 Shader *shader = scene->default_background;
1678
1679 if (world_recalc || update_all || b_world.ptr.data != world_map ||
1680 viewport_parameters.shader_modified(new_viewport_parameters) ||
1681 scene_attr_needs_recalc(shader, b_depsgraph))
1682 {
1683 unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
1684
1685 /* create nodes */
1686 if (new_viewport_parameters.use_scene_world && b_world && b_world.node_tree()) {
1687 BL::ShaderNodeTree b_ntree(b_world.node_tree());
1688
1689 add_nodes(scene, b_engine, b_data, b_scene, graph.get(), b_ntree);
1690
1691 /* volume */
1692 PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
1693 shader->set_volume_sampling_method(get_volume_sampling(cworld));
1694 shader->set_volume_interpolation_method(get_volume_interpolation(cworld));
1695 shader->set_volume_step_rate(get_float(cworld, "volume_step_size"));
1696 }
1697 else if (new_viewport_parameters.use_scene_world && b_world) {
1698 BackgroundNode *background = graph->create_node<BackgroundNode>();
1699 background->set_color(get_float3(b_world.color()));
1700
1701 ShaderNode *out = graph->output();
1702 graph->connect(background->output("Background"), out->input("Surface"));
1703 }
1704 else if (!new_viewport_parameters.use_scene_world) {
1705 float3 world_color;
1706 if (b_world) {
1707 world_color = get_float3(b_world.color());
1708 }
1709 else {
1710 world_color = zero_float3();
1711 }
1712
1713 BackgroundNode *background = graph->create_node<BackgroundNode>();
1714 LightPathNode *light_path = graph->create_node<LightPathNode>();
1715
1716 MixNode *mix_scene_with_background = graph->create_node<MixNode>();
1717 mix_scene_with_background->set_color2(world_color);
1718
1719 EnvironmentTextureNode *texture_environment = graph->create_node<EnvironmentTextureNode>();
1720 texture_environment->set_tex_mapping_type(TextureMapping::VECTOR);
1721 float3 rotation_z = texture_environment->get_tex_mapping_rotation();
1722 rotation_z[2] = new_viewport_parameters.studiolight_rotate_z;
1723 texture_environment->set_tex_mapping_rotation(rotation_z);
1724 texture_environment->set_filename(new_viewport_parameters.studiolight_path);
1725
1726 MixNode *mix_intensity = graph->create_node<MixNode>();
1727 mix_intensity->set_mix_type(NODE_MIX_MUL);
1728 mix_intensity->set_fac(1.0f);
1729 mix_intensity->set_color2(make_float3(new_viewport_parameters.studiolight_intensity,
1730 new_viewport_parameters.studiolight_intensity,
1731 new_viewport_parameters.studiolight_intensity));
1732
1733 TextureCoordinateNode *texture_coordinate = graph->create_node<TextureCoordinateNode>();
1734
1735 MixNode *mix_background_with_environment = graph->create_node<MixNode>();
1736 mix_background_with_environment->set_fac(
1737 new_viewport_parameters.studiolight_background_alpha);
1738 mix_background_with_environment->set_color1(world_color);
1739
1740 ShaderNode *out = graph->output();
1741
1742 graph->connect(texture_coordinate->output("Generated"),
1743 texture_environment->input("Vector"));
1744 graph->connect(texture_environment->output("Color"), mix_intensity->input("Color1"));
1745 graph->connect(light_path->output("Is Camera Ray"), mix_scene_with_background->input("Fac"));
1746 graph->connect(mix_intensity->output("Color"), mix_scene_with_background->input("Color1"));
1747 graph->connect(mix_intensity->output("Color"),
1748 mix_background_with_environment->input("Color2"));
1749 graph->connect(mix_background_with_environment->output("Color"),
1750 mix_scene_with_background->input("Color2"));
1751 graph->connect(mix_scene_with_background->output("Color"), background->input("Color"));
1752 graph->connect(background->output("Background"), out->input("Surface"));
1753 }
1754
1755 /* Visibility */
1756 if (b_world) {
1757 PointerRNA cvisibility = RNA_pointer_get(&b_world.ptr, "cycles_visibility");
1758 uint visibility = 0;
1759
1760 visibility |= get_boolean(cvisibility, "camera") ? PATH_RAY_CAMERA : PathRayFlag(0);
1761 visibility |= get_boolean(cvisibility, "diffuse") ? PATH_RAY_DIFFUSE : PathRayFlag(0);
1762 visibility |= get_boolean(cvisibility, "glossy") ? PATH_RAY_GLOSSY : PathRayFlag(0);
1763 visibility |= get_boolean(cvisibility, "transmission") ? PATH_RAY_TRANSMIT : PathRayFlag(0);
1764 visibility |= get_boolean(cvisibility, "scatter") ? PATH_RAY_VOLUME_SCATTER : PathRayFlag(0);
1765
1766 background->set_visibility(visibility);
1767 }
1768
1769 resolve_view_layer_attributes(shader, graph.get(), b_depsgraph);
1770
1771 shader->set_graph(std::move(graph));
1772 shader->tag_update(scene);
1773 }
1774
1775 /* Fast GI */
1776 if (b_world) {
1777 BL::WorldLighting b_light = b_world.light_settings();
1778 enum { FAST_GI_METHOD_REPLACE = 0, FAST_GI_METHOD_ADD = 1, FAST_GI_METHOD_NUM };
1779
1780 const bool use_fast_gi = get_boolean(cscene, "use_fast_gi");
1781 if (use_fast_gi) {
1782 const int fast_gi_method = get_enum(
1783 cscene, "fast_gi_method", FAST_GI_METHOD_NUM, FAST_GI_METHOD_REPLACE);
1784 integrator->set_ao_factor((fast_gi_method == FAST_GI_METHOD_REPLACE) ? b_light.ao_factor() :
1785 0.0f);
1786 integrator->set_ao_additive_factor(
1787 (fast_gi_method == FAST_GI_METHOD_ADD) ? b_light.ao_factor() : 0.0f);
1788 }
1789 else {
1790 integrator->set_ao_factor(0.0f);
1791 integrator->set_ao_additive_factor(0.0f);
1792 }
1793
1794 integrator->set_ao_distance(b_light.distance());
1795 }
1796 else {
1797 integrator->set_ao_factor(0.0f);
1798 integrator->set_ao_additive_factor(0.0f);
1799 integrator->set_ao_distance(10.0f);
1800 }
1801
1802 background->set_transparent(b_scene.render().film_transparent());
1803
1804 if (background->get_transparent()) {
1805 background->set_transparent_glass(get_boolean(cscene, "film_transparent_glass"));
1806 background->set_transparent_roughness_threshold(
1807 get_float(cscene, "film_transparent_roughness"));
1808 }
1809 else {
1810 background->set_transparent_glass(false);
1811 background->set_transparent_roughness_threshold(0.0f);
1812 }
1813
1814 background->set_use_shader(view_layer.use_background_shader ||
1815 viewport_parameters.use_custom_shader());
1816
1817 background->set_lightgroup(ustring(b_world ? b_world.lightgroup() : ""));
1818
1819 background->tag_update(scene);
1820}
1821
1822/* Sync Lights */
1823
1824void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
1825{
1826 shader_map.set_default(scene->default_light);
1827
1828 for (BL::ID &b_id : b_depsgraph.ids) {
1829 if (!b_id.is_a(&RNA_Light)) {
1830 continue;
1831 }
1832
1833 BL::Light b_light(b_id);
1834 Shader *shader;
1835
1836 /* test if we need to sync */
1837 if (shader_map.add_or_update(&shader, b_light) || update_all ||
1838 scene_attr_needs_recalc(shader, b_depsgraph))
1839 {
1840 unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
1841
1842 /* create nodes */
1843 if (b_light.use_nodes() && b_light.node_tree()) {
1844 shader->name = b_light.name().c_str();
1845
1846 BL::ShaderNodeTree b_ntree(b_light.node_tree());
1847
1848 add_nodes(scene, b_engine, b_data, b_scene, graph.get(), b_ntree);
1849 }
1850 else {
1851 EmissionNode *emission = graph->create_node<EmissionNode>();
1852 emission->set_color(one_float3());
1853 emission->set_strength(1.0f);
1854
1855 ShaderNode *out = graph->output();
1856 graph->connect(emission->output("Emission"), out->input("Surface"));
1857 }
1858
1859 resolve_view_layer_attributes(shader, graph.get(), b_depsgraph);
1860
1861 shader->set_graph(std::move(graph));
1862 shader->tag_update(scene);
1863 }
1864 }
1865}
1866
1867void BlenderSync::sync_shaders(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all)
1868{
1869 shader_map.pre_sync();
1870
1871 sync_world(b_depsgraph, b_v3d, update_all);
1872 sync_lights(b_depsgraph, update_all);
1873 sync_materials(b_depsgraph, update_all);
1874}
1875
bool BKE_view_layer_find_rgba_attribute(const Scene *scene, const ViewLayer *layer, const char *name, float r_value[4])
void BKE_id_free(Main *bmain, void *idv)
unsigned int uint
struct TaskPool TaskPool
Definition BLI_task.h:56
struct ViewLayer ViewLayer
NodeGaborType
struct Scene Scene
static float3 get_node_output_vector(BL::Node &b_node, const string &name)
static EmissionSampling get_emission_sampling(PointerRNA &ptr)
static float3 get_node_output_rgba(BL::Node &b_node, const string &name)
static VolumeSampling get_volume_sampling(PointerRNA &ptr)
static const string_view view_layer_attr_prefix("\x01layer:")
static DisplacementMethod get_displacement_method(BL::Material &b_mat)
static int validate_enum_value(const int value, const int num_values, const int default_value)
static BL::NodeSocket get_node_output(BL::Node &b_node, const string &name)
static ShaderInput * node_find_input_by_name(BL::Node b_node, ShaderNode *node, BL::NodeSocket &b_socket)
static ImageAlphaType get_image_alpha_type(BL::Image &b_image)
static void add_nodes(Scene *scene, BL::RenderEngine &b_engine, BL::BlendData &b_data, BL::Scene &b_scene, ShaderGraph *graph, BL::ShaderNodeTree &b_ntree, const ProxyMap &proxy_input_map, const ProxyMap &proxy_output_map)
static bool node_use_modified_socket_name(ShaderNode *node)
static ShaderNode * add_node(Scene *scene, BL::RenderEngine &b_engine, BL::BlendData &b_data, BL::Scene &b_scene, ShaderGraph *graph, BL::ShaderNodeTree &b_ntree, BL::ShaderNode &b_node)
static void add_nodes_inlined(Scene *scene, BL::RenderEngine &b_engine, BL::BlendData &b_data, BL::Scene &b_scene, ShaderGraph *graph, BL::ShaderNodeTree &b_ntree, const ProxyMap &proxy_input_map, const ProxyMap &proxy_output_map)
static ustring blender_attribute_name_add_type(const string &name, BlenderAttributeType type)
static bool is_image_animated(BL::Image::source_enum b_image_source, BL::ImageUser &b_image_user)
BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_real_name)
static ShaderOutput * node_find_output_by_name(BL::Node b_node, ShaderNode *node, BL::NodeSocket &b_socket)
static void set_default_value(ShaderInput *input, BL::NodeSocket &b_sock, BL::BlendData &b_data, BL::ID &b_id)
static VolumeInterpolation get_volume_interpolation(PointerRNA &ptr)
static const string_view instancer_attr_prefix("\x01instancer:")
map< string, ConvertNode * > ProxyMap
static float get_node_output_value(BL::Node &b_node, const string &name)
static void get_tex_mapping(TextureNode *mapping, BL::TexMapping &b_mapping)
static SocketType::Type convert_socket_type(BL::NodeSocket &b_socket)
unordered_multimap< void *, ShaderInput * > PtrInputMap
static ExtensionType get_image_extension(NodeType &b_node)
static const string_view object_attr_prefix("\x01object:")
static InterpolationType get_image_interpolation(NodeType &b_node)
map< void *, ShaderOutput * > PtrOutputMap
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition btVector3.h:263
ImageParams image_params() const
ImageParams image_params() const
OutputNode * output()
unique_ptr_vector< ShaderNode > nodes
T * create_node(Args &&...args)
void disconnect(ShaderOutput *from)
void connect(ShaderOutput *from, ShaderInput *to)
SocketType::Type type() const
bool constant_folded_in
void set(const float f)
ShaderInput * input(const char *name)
ShaderNodeSpecialType special_type
unique_ptr_vector< ShaderInput > inputs
ShaderOutput * output(const char *name)
unique_ptr_vector< ShaderOutput > outputs
void set_graph(unique_ptr< ShaderGraph > &&graph)
void tag_update(Scene *scene)
NODE_DECLARE unique_ptr< ShaderGraph > graph
void tag_used(Scene *scene)
void push_back_slow(const T &t)
T * find(const BL::ID &id)
Definition id_map.h:40
BL::ShaderNodeAttribute::attribute_type_enum BlenderAttributeType
static void curvemapping_minmax(BL::CurveMapping &cumap, const int num_curves, float *min_x, float *max_x)
static float4 get_float4(const BL::Array< float, 4 > &array)
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 string get_enum_identifier(PointerRNA &ptr, const char *name)
static string get_text_datablock_content(const PointerRNA &ptr)
static float3 get_float3(const BL::Array< float, 2 > &array)
static int get_enum(PointerRNA &ptr, const char *name, int num_values=-1, int default_value=-1)
static void colorramp_to_array(BL::ColorRamp &ramp, array< float3 > &ramp_color, array< float > &ramp_alpha, const int size)
static string blender_absolute_path(BL::BlendData &b_data, BL::ID &b_id, const string &path)
static void curvemapping_float_to_array(BL::CurveMapping &cumap, array< float > &data, const int size)
static void curvemapping_color_to_array(BL::CurveMapping &cumap, array< float3 > &data, const int size, bool rgb_curve)
static int image_user_frame_number(BL::ImageUser &iuser, BL::Image &ima, const int cfra)
static string get_string(PointerRNA &ptr, const char *name)
static Transform get_transform(const BL::Array< float, 16 > &array)
static string image_user_file_path(BL::BlendData &data, BL::ImageUser &iuser, BL::Image &ima, const int cfra)
#define RAMP_TABLE_SIZE
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define input
#define assert(assertion)
#define out
#define output
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, 4 > float4
VecBase< float, 3 > float3
uint tex_coord
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
NodeClampType
NodeEnvironmentProjection
NodeMathType
NodeMapRangeType
NodeWaveBandsDirection
NodeMappingType
NodePrincipledHairModel
@ NODE_PRINCIPLED_HAIR_MODEL_NUM
@ NODE_PRINCIPLED_HAIR_HUANG
NodeNoiseType
NodeVectorTransformConvertSpace
NodeTangentAxis
NodePrincipledHairParametrization
@ NODE_PRINCIPLED_HAIR_REFLECTANCE
@ NODE_PRINCIPLED_HAIR_PARAMETRIZATION_NUM
NodeVoronoiFeature
NodeWaveType
NodeVoronoiDistanceMetric
NodeSkyType
NodeWaveProfile
@ NODE_MIX_MUL
@ CLOSURE_VOLUME_RAYLEIGH_ID
@ CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID
@ CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID
@ CLOSURE_VOLUME_MIE_ID
@ CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID
@ CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID
@ CLOSURE_BSSRDF_BURLEY_ID
@ CLOSURE_BSDF_SHEEN_ID
@ CLOSURE_BSDF_DIFFUSE_TOON_ID
@ CLOSURE_VOLUME_DRAINE_ID
@ CLOSURE_BSDF_MICROFACET_GGX_ID
@ CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID
@ CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID
@ CLOSURE_BSDF_HAIR_TRANSMISSION_ID
@ CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID
@ CLOSURE_VOLUME_FOURNIER_FORAND_ID
@ CLOSURE_BSSRDF_RANDOM_WALK_ID
@ CLOSURE_BSDF_PHYSICAL_CONDUCTOR
@ CLOSURE_BSDF_MICROFACET_BECKMANN_ID
@ CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID
@ CLOSURE_BSDF_F82_CONDUCTOR
@ CLOSURE_BSDF_GLOSSY_TOON_ID
@ CLOSURE_BSDF_HAIR_REFLECTION_ID
@ CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID
@ CLOSURE_BSDF_ASHIKHMIN_VELVET_ID
NodeVectorRotateType
NodeVectorTransformType
NodeImageProjection
NodeCombSepColorType
NodeGradientType
NodeTangentDirectionType
NodeVectorMathType
NodeWaveRingsDirection
NodeNormalMapSpace
PathRayFlag
@ PATH_RAY_TRANSMIT
@ PATH_RAY_VOLUME_SCATTER
@ PATH_RAY_GLOSSY
@ PATH_RAY_DIFFUSE
@ PATH_RAY_CAMERA
EmissionSampling
@ EMISSION_SAMPLING_NUM
@ EMISSION_SAMPLING_AUTO
ccl_device_inline float3 one_float3()
Definition math_float3.h:26
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:17
bNodeTree * node_tree_add_tree(Main *bmain, StringRef name, StringRef idname)
Definition node.cc:4085
bool inline_shader_node_tree(const bNodeTree &src_tree, bNodeTree &dst_tree, InlineShaderNodeTreeParams &params)
closure color scatter(string phase, float Anisotropy, float IOR, float Backscatter, float Alpha, float Diameter)
static blender::bke::bNodeSocketTemplate inputs[]
static float noise(int n)
const char * name
#define mix
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
const PointerRNA PointerRNA_NULL
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
float RNA_float_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_id_pointer_create(ID *id)
VolumeInterpolation
@ VOLUME_NUM_INTERPOLATION
@ VOLUME_INTERPOLATION_LINEAR
DisplacementMethod
@ DISPLACE_NUM_METHODS
@ DISPLACE_BUMP
VolumeSampling
@ VOLUME_NUM_SAMPLING
@ VOLUME_SAMPLING_DISTANCE
@ SHADER_SPECIAL_TYPE_OSL
closure color sheen(normal N, float roughness) BUILTIN
bool string_startswith(const string_view s, const string_view start)
Definition string.cpp:104
void string_replace(string &haystack, const string &needle, const string &other)
Definition string.cpp:145
bool string_endswith(const string_view s, const string_view end)
Definition string.cpp:120
char name[258]
Definition DNA_ID.h:432
void set(const SocketType &input, bool value)
void set_value(const SocketType &socket, const Node &other, const SocketType &other_socket)
ustring name
Definition graph/node.h:177
bool is_a(const NodeType *type)
unique_ptr< ShaderManager > shader_manager
Definition scene.h:148
unique_ptr< ImageManager > image_manager
Definition scene.h:145
static bool is_float3(Type type)
void push(TaskRunFunction &&task)
Definition task.cpp:21
void wait_work(Summary *stats=nullptr)
Definition task.cpp:27
char idname[64]
float y
Definition sky_math.h:225
float z
Definition sky_math.h:225
float x
Definition sky_math.h:225
float w
Definition sky_math.h:225
ImageAlphaType
Definition texture.h:58
@ IMAGE_ALPHA_NUM_TYPES
Definition texture.h:65
@ IMAGE_ALPHA_AUTO
Definition texture.h:63
InterpolationType
Definition texture.h:22
@ INTERPOLATION_LINEAR
Definition texture.h:24
@ INTERPOLATION_NUM_TYPES
Definition texture.h:29
ExtensionType
Definition texture.h:71
@ EXTENSION_REPEAT
Definition texture.h:73
@ EXTENSION_NUM_TYPES
Definition texture.h:81
static int magic(const Tex *tex, const float texvec[3], TexResult *texres)
PointerRNA * ptr
Definition wm_files.cc:4238