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