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