Blender V4.3
shader_nodes.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
6#include "scene/colorspace.h"
8#include "scene/film.h"
9#include "scene/image.h"
10#include "scene/image_sky.h"
11#include "scene/integrator.h"
12#include "scene/light.h"
13#include "scene/mesh.h"
14#include "scene/osl.h"
15#include "scene/scene.h"
16#include "scene/svm.h"
17
18#include "sky_model.h"
19
20#include "util/color.h"
21#include "util/foreach.h"
22#include "util/log.h"
23#include "util/transform.h"
24
25#include "kernel/tables.h"
26
31
33
34/* Texture Mapping */
35
36#define TEXTURE_MAPPING_DEFINE(TextureNode) \
37 SOCKET_POINT(tex_mapping.translation, "Translation", zero_float3()); \
38 SOCKET_VECTOR(tex_mapping.rotation, "Rotation", zero_float3()); \
39 SOCKET_VECTOR(tex_mapping.scale, "Scale", one_float3()); \
40\
41 SOCKET_VECTOR(tex_mapping.min, "Min", make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX)); \
42 SOCKET_VECTOR(tex_mapping.max, "Max", make_float3(FLT_MAX, FLT_MAX, FLT_MAX)); \
43 SOCKET_BOOLEAN(tex_mapping.use_minmax, "Use Min Max", false); \
44\
45 static NodeEnum mapping_axis_enum; \
46 mapping_axis_enum.insert("none", TextureMapping::NONE); \
47 mapping_axis_enum.insert("x", TextureMapping::X); \
48 mapping_axis_enum.insert("y", TextureMapping::Y); \
49 mapping_axis_enum.insert("z", TextureMapping::Z); \
50 SOCKET_ENUM(tex_mapping.x_mapping, "x_mapping", mapping_axis_enum, TextureMapping::X); \
51 SOCKET_ENUM(tex_mapping.y_mapping, "y_mapping", mapping_axis_enum, TextureMapping::Y); \
52 SOCKET_ENUM(tex_mapping.z_mapping, "z_mapping", mapping_axis_enum, TextureMapping::Z); \
53\
54 static NodeEnum mapping_type_enum; \
55 mapping_type_enum.insert("point", TextureMapping::POINT); \
56 mapping_type_enum.insert("texture", TextureMapping::TEXTURE); \
57 mapping_type_enum.insert("vector", TextureMapping::VECTOR); \
58 mapping_type_enum.insert("normal", TextureMapping::NORMAL); \
59 SOCKET_ENUM(tex_mapping.type, "Type", mapping_type_enum, TextureMapping::TEXTURE); \
60\
61 static NodeEnum mapping_projection_enum; \
62 mapping_projection_enum.insert("flat", TextureMapping::FLAT); \
63 mapping_projection_enum.insert("cube", TextureMapping::CUBE); \
64 mapping_projection_enum.insert("tube", TextureMapping::TUBE); \
65 mapping_projection_enum.insert("sphere", TextureMapping::SPHERE); \
66 SOCKET_ENUM(tex_mapping.projection, "Projection", mapping_projection_enum, TextureMapping::FLAT);
67
69
71{
73
74 if (x_mapping != NONE) {
75 mmat[0][x_mapping - 1] = 1.0f;
76 }
77 if (y_mapping != NONE) {
78 mmat[1][y_mapping - 1] = 1.0f;
79 }
80 if (z_mapping != NONE) {
81 mmat[2][z_mapping - 1] = 1.0f;
82 }
83
84 float3 scale_clamped = scale;
85
86 if (type == TEXTURE || type == NORMAL) {
87 /* keep matrix invertible */
88 if (fabsf(scale.x) < 1e-5f) {
89 scale_clamped.x = signf(scale.x) * 1e-5f;
90 }
91 if (fabsf(scale.y) < 1e-5f) {
92 scale_clamped.y = signf(scale.y) * 1e-5f;
93 }
94 if (fabsf(scale.z) < 1e-5f) {
95 scale_clamped.z = signf(scale.z) * 1e-5f;
96 }
97 }
98
99 Transform smat = transform_scale(scale_clamped);
100 Transform rmat = transform_euler(rotation);
102
103 Transform mat;
104
105 switch (type) {
106 case TEXTURE:
107 /* inverse transform on texture coordinate gives
108 * forward transform on texture */
109 mat = tmat * rmat * smat;
110 mat = transform_inverse(mat);
111 break;
112 case POINT:
113 /* full transform */
114 mat = tmat * rmat * smat;
115 break;
116 case VECTOR:
117 /* no translation for vectors */
118 mat = rmat * smat;
119 break;
120 case NORMAL:
121 /* no translation for normals, and inverse transpose */
122 mat = rmat * smat;
124 break;
125 }
126
127 /* projection last */
128 mat = mat * mmat;
129
130 return mat;
131}
132
134{
135 if (translation != zero_float3()) {
136 return false;
137 }
138 if (rotation != zero_float3()) {
139 return false;
140 }
141 if (scale != one_float3()) {
142 return false;
143 }
144
145 if (x_mapping != X || y_mapping != Y || z_mapping != Z) {
146 return false;
147 }
148 if (use_minmax) {
149 return false;
150 }
151
152 return true;
153}
154
155void TextureMapping::compile(SVMCompiler &compiler, int offset_in, int offset_out)
156{
157 compiler.add_node(NODE_TEXTURE_MAPPING, offset_in, offset_out);
158
160 compiler.add_node(tfm.x);
161 compiler.add_node(tfm.y);
162 compiler.add_node(tfm.z);
163
164 if (use_minmax) {
165 compiler.add_node(NODE_MIN_MAX, offset_out, offset_out);
166 compiler.add_node(float3_to_float4(min));
167 compiler.add_node(float3_to_float4(max));
168 }
169
170 if (type == NORMAL) {
171 compiler.add_node(NODE_VECTOR_MATH,
173 compiler.encode_uchar4(offset_out, offset_out, offset_out),
174 compiler.encode_uchar4(SVM_STACK_INVALID, offset_out));
175 }
176}
177
178/* Convenience function for texture nodes, allocating stack space to output
179 * a modified vector and returning its offset */
181{
182 if (!skip()) {
183 int offset_in = compiler.stack_assign(vector_in);
184 int offset_out = compiler.stack_find_offset(SocketType::VECTOR);
185
186 compile(compiler, offset_in, offset_out);
187
188 return offset_out;
189 }
190
191 return compiler.stack_assign(vector_in);
192}
193
194void TextureMapping::compile_end(SVMCompiler &compiler, ShaderInput *vector_in, int vector_offset)
195{
196 if (!skip()) {
197 compiler.stack_clear_offset(vector_in->type(), vector_offset);
198 }
199}
200
202{
203 if (!skip()) {
204 compiler.parameter("mapping", compute_transform());
205 compiler.parameter("use_mapping", 1);
206 }
207}
208
209/* Image Texture */
210
212{
213 NodeType *type = NodeType::add("image_texture", create, NodeType::SHADER);
214
216
217 SOCKET_STRING(filename, "Filename", ustring());
218 SOCKET_STRING(colorspace, "Colorspace", u_colorspace_auto);
219
220 static NodeEnum alpha_type_enum;
221 alpha_type_enum.insert("auto", IMAGE_ALPHA_AUTO);
222 alpha_type_enum.insert("unassociated", IMAGE_ALPHA_UNASSOCIATED);
223 alpha_type_enum.insert("associated", IMAGE_ALPHA_ASSOCIATED);
224 alpha_type_enum.insert("channel_packed", IMAGE_ALPHA_CHANNEL_PACKED);
225 alpha_type_enum.insert("ignore", IMAGE_ALPHA_IGNORE);
226 SOCKET_ENUM(alpha_type, "Alpha Type", alpha_type_enum, IMAGE_ALPHA_AUTO);
227
228 static NodeEnum interpolation_enum;
229 interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
230 interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
231 interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
232 interpolation_enum.insert("smart", INTERPOLATION_SMART);
233 SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
234
235 static NodeEnum extension_enum;
236 extension_enum.insert("periodic", EXTENSION_REPEAT);
237 extension_enum.insert("clamp", EXTENSION_EXTEND);
238 extension_enum.insert("black", EXTENSION_CLIP);
239 extension_enum.insert("mirror", EXTENSION_MIRROR);
240 SOCKET_ENUM(extension, "Extension", extension_enum, EXTENSION_REPEAT);
241
242 static NodeEnum projection_enum;
243 projection_enum.insert("flat", NODE_IMAGE_PROJ_FLAT);
244 projection_enum.insert("box", NODE_IMAGE_PROJ_BOX);
245 projection_enum.insert("sphere", NODE_IMAGE_PROJ_SPHERE);
246 projection_enum.insert("tube", NODE_IMAGE_PROJ_TUBE);
247 SOCKET_ENUM(projection, "Projection", projection_enum, NODE_IMAGE_PROJ_FLAT);
248
249 SOCKET_FLOAT(projection_blend, "Projection Blend", 0.0f);
250
251 SOCKET_INT_ARRAY(tiles, "Tiles", array<int>());
252 SOCKET_BOOLEAN(animated, "Animated", false);
253
255
256 SOCKET_OUT_COLOR(color, "Color");
257 SOCKET_OUT_FLOAT(alpha, "Alpha");
258
259 return type;
260}
261
262ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(get_node_type())
263{
264 colorspace = u_colorspace_raw;
265 animated = false;
266 tiles.push_back_slow(1001);
267}
268
270{
271 ImageTextureNode *node = graph->create_node<ImageTextureNode>(*this);
272 node->handle = handle;
273 return node;
274}
275
277{
279 params.animated = animated;
280 params.interpolation = interpolation;
281 params.extension = extension;
282 params.alpha_type = alpha_type;
283 params.colorspace = colorspace;
284 return params;
285}
286
288{
289 /* Box projection computes its own UVs that always lie in the
290 * 1001 tile, so there's no point in loading any others. */
291 if (projection == NODE_IMAGE_PROJ_BOX) {
292 tiles.clear();
293 tiles.push_back_slow(1001);
294 return;
295 }
296
297 if (!scene->params.background) {
298 /* During interactive renders, all tiles are loaded.
299 * While we could support updating this when UVs change, that could lead
300 * to annoying interruptions when loading images while editing UVs. */
301 return;
302 }
303
304 /* Only check UVs for tile culling if there are multiple tiles. */
305 if (tiles.size() < 2) {
306 return;
307 }
308
309 ShaderInput *vector_in = input("Vector");
310 ustring attribute;
311 if (vector_in->link) {
312 ShaderNode *node = vector_in->link->parent;
313 if (node->type == UVMapNode::get_node_type()) {
314 UVMapNode *uvmap = (UVMapNode *)node;
315 attribute = uvmap->get_attribute();
316 }
317 else if (node->type == TextureCoordinateNode::get_node_type()) {
318 if (vector_in->link != node->output("UV")) {
319 return;
320 }
321 }
322 else {
323 return;
324 }
325 }
326
327 unordered_set<int> used_tiles;
328 /* TODO(lukas): This is quite inefficient. A fairly simple improvement would
329 * be to have a cache in each mesh that is indexed by attribute.
330 * Additionally, building a graph-to-meshes list once could help. */
331 foreach (Geometry *geom, scene->geometry) {
332 foreach (Node *node, geom->get_used_shaders()) {
333 Shader *shader = static_cast<Shader *>(node);
334 if (shader->graph == graph) {
335 geom->get_uv_tiles(attribute, used_tiles);
336 }
337 }
338 }
339
340 array<int> new_tiles;
341 foreach (int tile, tiles) {
342 if (used_tiles.count(tile)) {
343 new_tiles.push_back_slow(tile);
344 }
345 }
346 tiles.steal_data(new_tiles);
347}
348
350{
351#ifdef WITH_PTEX
352 /* todo: avoid loading other texture coordinates when using ptex,
353 * and hide texture coordinate socket in the UI */
354 if (shader->has_surface_link() && string_endswith(filename, ".ptx")) {
355 /* ptex */
356 attributes->add(ATTR_STD_PTEX_FACE_ID);
357 attributes->add(ATTR_STD_PTEX_UV);
358 }
359#endif
360
361 ShaderNode::attributes(shader, attributes);
362}
363
365{
366 ShaderInput *vector_in = input("Vector");
367 ShaderOutput *color_out = output("Color");
368 ShaderOutput *alpha_out = output("Alpha");
369
370 if (handle.empty()) {
371 cull_tiles(compiler.scene, compiler.current_graph);
372 ImageManager *image_manager = compiler.scene->image_manager;
373 handle = image_manager->add_image(filename.string(), image_params(), tiles);
374 }
375
376 /* All tiles have the same metadata. */
377 const ImageMetaData metadata = handle.metadata();
378 const bool compress_as_srgb = metadata.compress_as_srgb;
379 const ustring known_colorspace = metadata.colorspace;
380
381 int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
382 uint flags = 0;
383
384 if (compress_as_srgb) {
386 }
387 if (!alpha_out->links.empty()) {
388 const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) ||
389 alpha_type == IMAGE_ALPHA_CHANNEL_PACKED ||
390 alpha_type == IMAGE_ALPHA_IGNORE);
391
392 if (unassociate_alpha) {
394 }
395 }
396
397 if (projection != NODE_IMAGE_PROJ_BOX) {
398 /* If there only is one image (a very common case), we encode it as a negative value. */
399 int num_nodes;
400 if (handle.num_tiles() == 1) {
401 num_nodes = -handle.svm_slot();
402 }
403 else {
404 num_nodes = divide_up(handle.num_tiles(), 2);
405 }
406
407 compiler.add_node(NODE_TEX_IMAGE,
408 num_nodes,
409 compiler.encode_uchar4(vector_offset,
410 compiler.stack_assign_if_linked(color_out),
411 compiler.stack_assign_if_linked(alpha_out),
412 flags),
413 projection);
414
415 if (num_nodes > 0) {
416 for (int i = 0; i < num_nodes; i++) {
417 int4 node;
418 node.x = tiles[2 * i];
419 node.y = handle.svm_slot(2 * i);
420 if (2 * i + 1 < tiles.size()) {
421 node.z = tiles[2 * i + 1];
422 node.w = handle.svm_slot(2 * i + 1);
423 }
424 else {
425 node.z = -1;
426 node.w = -1;
427 }
428 compiler.add_node(node.x, node.y, node.z, node.w);
429 }
430 }
431 }
432 else {
433 assert(handle.num_tiles() == 1);
434 compiler.add_node(NODE_TEX_IMAGE_BOX,
435 handle.svm_slot(),
436 compiler.encode_uchar4(vector_offset,
437 compiler.stack_assign_if_linked(color_out),
438 compiler.stack_assign_if_linked(alpha_out),
439 flags),
440 __float_as_int(projection_blend));
441 }
442
443 tex_mapping.compile_end(compiler, vector_in, vector_offset);
444}
445
447{
448 ShaderOutput *alpha_out = output("Alpha");
449
450 tex_mapping.compile(compiler);
451
452 if (handle.empty()) {
453 ImageManager *image_manager = compiler.scene->image_manager;
454 handle = image_manager->add_image(filename.string(), image_params());
455 }
456
457 const ImageMetaData metadata = handle.metadata();
458 const bool is_float = metadata.is_float();
459 const bool compress_as_srgb = metadata.compress_as_srgb;
460 const ustring known_colorspace = metadata.colorspace;
461
462 if (handle.svm_slot() == -1) {
463 compiler.parameter_texture(
464 "filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace);
465 }
466 else {
467 compiler.parameter_texture("filename", handle);
468 }
469
470 const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) ||
471 alpha_type == IMAGE_ALPHA_CHANNEL_PACKED ||
472 alpha_type == IMAGE_ALPHA_IGNORE);
473 const bool is_tiled = (filename.find("<UDIM>") != string::npos ||
474 filename.find("<UVTILE>") != string::npos) ||
475 handle.num_tiles() > 1;
476
477 compiler.parameter(this, "projection");
478 compiler.parameter(this, "projection_blend");
479 compiler.parameter("compress_as_srgb", compress_as_srgb);
480 compiler.parameter("ignore_alpha", alpha_type == IMAGE_ALPHA_IGNORE);
481 compiler.parameter("unassociate_alpha", !alpha_out->links.empty() && unassociate_alpha);
482 compiler.parameter("is_float", is_float);
483 compiler.parameter("is_tiled", is_tiled);
484 compiler.parameter(this, "interpolation");
485 compiler.parameter(this, "extension");
486
487 compiler.add(this, "node_image_texture");
488}
489
490/* Environment Texture */
491
493{
494 NodeType *type = NodeType::add("environment_texture", create, NodeType::SHADER);
495
497
498 SOCKET_STRING(filename, "Filename", ustring());
499 SOCKET_STRING(colorspace, "Colorspace", u_colorspace_auto);
500
501 static NodeEnum alpha_type_enum;
502 alpha_type_enum.insert("auto", IMAGE_ALPHA_AUTO);
503 alpha_type_enum.insert("unassociated", IMAGE_ALPHA_UNASSOCIATED);
504 alpha_type_enum.insert("associated", IMAGE_ALPHA_ASSOCIATED);
505 alpha_type_enum.insert("channel_packed", IMAGE_ALPHA_CHANNEL_PACKED);
506 alpha_type_enum.insert("ignore", IMAGE_ALPHA_IGNORE);
507 SOCKET_ENUM(alpha_type, "Alpha Type", alpha_type_enum, IMAGE_ALPHA_AUTO);
508
509 static NodeEnum interpolation_enum;
510 interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
511 interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
512 interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
513 interpolation_enum.insert("smart", INTERPOLATION_SMART);
514 SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
515
516 static NodeEnum projection_enum;
517 projection_enum.insert("equirectangular", NODE_ENVIRONMENT_EQUIRECTANGULAR);
518 projection_enum.insert("mirror_ball", NODE_ENVIRONMENT_MIRROR_BALL);
519 SOCKET_ENUM(projection, "Projection", projection_enum, NODE_ENVIRONMENT_EQUIRECTANGULAR);
520
521 SOCKET_BOOLEAN(animated, "Animated", false);
522
524
525 SOCKET_OUT_COLOR(color, "Color");
526 SOCKET_OUT_FLOAT(alpha, "Alpha");
527
528 return type;
529}
530
531EnvironmentTextureNode::EnvironmentTextureNode() : ImageSlotTextureNode(get_node_type())
532{
533 colorspace = u_colorspace_raw;
534 animated = false;
535}
536
538{
539 EnvironmentTextureNode *node = graph->create_node<EnvironmentTextureNode>(*this);
540 node->handle = handle;
541 return node;
542}
543
545{
547 params.animated = animated;
548 params.interpolation = interpolation;
549 params.extension = EXTENSION_REPEAT;
550 params.alpha_type = alpha_type;
551 params.colorspace = colorspace;
552 return params;
553}
554
556{
557#ifdef WITH_PTEX
558 if (shader->has_surface_link() && string_endswith(filename, ".ptx")) {
559 /* ptex */
560 attributes->add(ATTR_STD_PTEX_FACE_ID);
561 attributes->add(ATTR_STD_PTEX_UV);
562 }
563#endif
564
565 ShaderNode::attributes(shader, attributes);
566}
567
569{
570 ShaderInput *vector_in = input("Vector");
571 ShaderOutput *color_out = output("Color");
572 ShaderOutput *alpha_out = output("Alpha");
573
574 if (handle.empty()) {
575 ImageManager *image_manager = compiler.scene->image_manager;
576 handle = image_manager->add_image(filename.string(), image_params());
577 }
578
579 const ImageMetaData metadata = handle.metadata();
580 const bool compress_as_srgb = metadata.compress_as_srgb;
581 const ustring known_colorspace = metadata.colorspace;
582
583 int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
584 uint flags = 0;
585
586 if (compress_as_srgb) {
588 }
589
590 compiler.add_node(NODE_TEX_ENVIRONMENT,
591 handle.svm_slot(),
592 compiler.encode_uchar4(vector_offset,
593 compiler.stack_assign_if_linked(color_out),
594 compiler.stack_assign_if_linked(alpha_out),
595 flags),
596 projection);
597
598 tex_mapping.compile_end(compiler, vector_in, vector_offset);
599}
600
602{
603 if (handle.empty()) {
604 ImageManager *image_manager = compiler.scene->image_manager;
605 handle = image_manager->add_image(filename.string(), image_params());
606 }
607
608 tex_mapping.compile(compiler);
609
610 const ImageMetaData metadata = handle.metadata();
611 const bool is_float = metadata.is_float();
612 const bool compress_as_srgb = metadata.compress_as_srgb;
613 const ustring known_colorspace = metadata.colorspace;
614
615 if (handle.svm_slot() == -1) {
616 compiler.parameter_texture(
617 "filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace);
618 }
619 else {
620 compiler.parameter_texture("filename", handle);
621 }
622
623 compiler.parameter(this, "projection");
624 compiler.parameter(this, "interpolation");
625 compiler.parameter("compress_as_srgb", compress_as_srgb);
626 compiler.parameter("ignore_alpha", alpha_type == IMAGE_ALPHA_IGNORE);
627 compiler.parameter("is_float", is_float);
628 compiler.add(this, "node_environment_texture");
629}
630
631/* Sky Texture */
632
634{
635 return make_float2(acosf(dir.z), atan2f(dir.x, dir.y));
636}
637
638typedef struct SunSky {
639 /* sun direction in spherical and cartesian */
640 float theta, phi;
641
642 /* Parameter */
644 float config_x[9], config_y[9], config_z[9], nishita_data[10];
646
647/* Preetham model */
648static float sky_perez_function(float lam[6], float theta, float gamma)
649{
650 return (1.0f + lam[0] * expf(lam[1] / cosf(theta))) *
651 (1.0f + lam[2] * expf(lam[3] * gamma) + lam[4] * cosf(gamma) * cosf(gamma));
652}
653
654static void sky_texture_precompute_preetham(SunSky *sunsky, float3 dir, float turbidity)
655{
656 /*
657 * We re-use the SunSky struct of the new model, to avoid extra variables
658 * zenith_Y/x/y is now radiance_x/y/z
659 * perez_Y/x/y is now config_x/y/z
660 */
661
662 float2 spherical = sky_spherical_coordinates(dir);
663 float theta = spherical.x;
664 float phi = spherical.y;
665
666 sunsky->theta = theta;
667 sunsky->phi = phi;
668
669 float theta2 = theta * theta;
670 float theta3 = theta2 * theta;
671 float T = turbidity;
672 float T2 = T * T;
673
674 float chi = (4.0f / 9.0f - T / 120.0f) * (M_PI_F - 2.0f * theta);
675 sunsky->radiance_x = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f;
676 sunsky->radiance_x *= 0.06f;
677
678 sunsky->radiance_y = (0.00166f * theta3 - 0.00375f * theta2 + 0.00209f * theta) * T2 +
679 (-0.02903f * theta3 + 0.06377f * theta2 - 0.03202f * theta + 0.00394f) * T +
680 (0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * theta + 0.25886f);
681
682 sunsky->radiance_z = (0.00275f * theta3 - 0.00610f * theta2 + 0.00317f * theta) * T2 +
683 (-0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * theta + 0.00516f) * T +
684 (0.15346f * theta3 - 0.26756f * theta2 + 0.06670f * theta + 0.26688f);
685
686 sunsky->config_x[0] = (0.1787f * T - 1.4630f);
687 sunsky->config_x[1] = (-0.3554f * T + 0.4275f);
688 sunsky->config_x[2] = (-0.0227f * T + 5.3251f);
689 sunsky->config_x[3] = (0.1206f * T - 2.5771f);
690 sunsky->config_x[4] = (-0.0670f * T + 0.3703f);
691
692 sunsky->config_y[0] = (-0.0193f * T - 0.2592f);
693 sunsky->config_y[1] = (-0.0665f * T + 0.0008f);
694 sunsky->config_y[2] = (-0.0004f * T + 0.2125f);
695 sunsky->config_y[3] = (-0.0641f * T - 0.8989f);
696 sunsky->config_y[4] = (-0.0033f * T + 0.0452f);
697
698 sunsky->config_z[0] = (-0.0167f * T - 0.2608f);
699 sunsky->config_z[1] = (-0.0950f * T + 0.0092f);
700 sunsky->config_z[2] = (-0.0079f * T + 0.2102f);
701 sunsky->config_z[3] = (-0.0441f * T - 1.6537f);
702 sunsky->config_z[4] = (-0.0109f * T + 0.0529f);
703
704 /* unused for old sky model */
705 for (int i = 5; i < 9; i++) {
706 sunsky->config_x[i] = 0.0f;
707 sunsky->config_y[i] = 0.0f;
708 sunsky->config_z[i] = 0.0f;
709 }
710
711 sunsky->radiance_x /= sky_perez_function(sunsky->config_x, 0, theta);
712 sunsky->radiance_y /= sky_perez_function(sunsky->config_y, 0, theta);
713 sunsky->radiance_z /= sky_perez_function(sunsky->config_z, 0, theta);
714}
715
716/* Hosek / Wilkie */
718 float3 dir,
719 float turbidity,
720 float ground_albedo)
721{
722 /* Calculate Sun Direction and save coordinates */
723 float2 spherical = sky_spherical_coordinates(dir);
724 float theta = spherical.x;
725 float phi = spherical.y;
726
727 /* Clamp Turbidity */
728 turbidity = clamp(turbidity, 0.0f, 10.0f);
729
730 /* Clamp to Horizon */
731 theta = clamp(theta, 0.0f, M_PI_2_F);
732
733 sunsky->theta = theta;
734 sunsky->phi = phi;
735
736 float solarElevation = M_PI_2_F - theta;
737
738 /* Initialize Sky Model */
739 SKY_ArHosekSkyModelState *sky_state;
741 (double)turbidity, (double)ground_albedo, (double)solarElevation);
742
743 /* Copy values from sky_state to SunSky */
744 for (int i = 0; i < 9; ++i) {
745 sunsky->config_x[i] = (float)sky_state->configs[0][i];
746 sunsky->config_y[i] = (float)sky_state->configs[1][i];
747 sunsky->config_z[i] = (float)sky_state->configs[2][i];
748 }
749 sunsky->radiance_x = (float)sky_state->radiances[0];
750 sunsky->radiance_y = (float)sky_state->radiances[1];
751 sunsky->radiance_z = (float)sky_state->radiances[2];
752
753 /* Free sky_state */
755}
756
757/* Nishita improved */
759 bool sun_disc,
760 float sun_size,
761 float sun_intensity,
762 float sun_elevation,
763 float sun_rotation,
764 float altitude,
765 float air_density,
766 float dust_density)
767{
768 /* sample 2 sun pixels */
769 float pixel_bottom[3];
770 float pixel_top[3];
772 sun_elevation, sun_size, altitude, air_density, dust_density, pixel_bottom, pixel_top);
773
774 /* send data to svm_sky */
775 sunsky->nishita_data[0] = pixel_bottom[0];
776 sunsky->nishita_data[1] = pixel_bottom[1];
777 sunsky->nishita_data[2] = pixel_bottom[2];
778 sunsky->nishita_data[3] = pixel_top[0];
779 sunsky->nishita_data[4] = pixel_top[1];
780 sunsky->nishita_data[5] = pixel_top[2];
781 sunsky->nishita_data[6] = sun_elevation;
782 sunsky->nishita_data[7] = sun_rotation;
783 sunsky->nishita_data[8] = sun_disc ? sun_size : -1.0f;
784 sunsky->nishita_data[9] = sun_intensity;
785}
786
788{
789 float clamped_altitude = clamp(altitude, 1.0f, 59999.0f);
790 float angular_diameter = get_sun_size();
791
792 float pix_bottom[3];
793 float pix_top[3];
795 angular_diameter,
796 clamped_altitude,
797 air_density,
798 dust_density,
799 pix_bottom,
800 pix_top);
801
802 /* Approximate the direction's elevation as the sun's elevation. */
803 float dir_elevation = sun_elevation;
804 float half_angular = angular_diameter / 2.0f;
805 float3 pixel_bottom = make_float3(pix_bottom[0], pix_bottom[1], pix_bottom[2]);
806 float3 pixel_top = make_float3(pix_top[0], pix_top[1], pix_top[2]);
807
808 /* Same code as in the sun evaluation shader. */
809 float3 xyz = make_float3(0.0f, 0.0f, 0.0f);
810 float y = 0.0f;
811 if (sun_elevation - half_angular > 0.0f) {
812 if (sun_elevation + half_angular > 0.0f) {
813 y = ((dir_elevation - sun_elevation) / angular_diameter) + 0.5f;
814 xyz = interp(pixel_bottom, pixel_top, y) * sun_intensity;
815 }
816 }
817 else {
818 if (sun_elevation + half_angular > 0.0f) {
819 y = dir_elevation / (sun_elevation + half_angular);
820 xyz = interp(pixel_bottom, pixel_top, y) * sun_intensity;
821 }
822 }
823
824 /* We first approximate the sun's contribution by
825 * multiplying the evaluated point by the square of the angular diameter.
826 * Then we scale the approximation using a piecewise function (determined empirically). */
827 float sun_contribution = average(xyz) * sqr(angular_diameter);
828
829 float first_point = 0.8f / 180.0f * M_PI_F;
830 float second_point = 1.0f / 180.0f * M_PI_F;
831 float third_point = M_PI_2_F;
832 if (angular_diameter < first_point) {
833 sun_contribution *= 1.0f;
834 }
835 else if (angular_diameter < second_point) {
836 float diff = angular_diameter - first_point;
837 float slope = (0.8f - 1.0f) / (second_point - first_point);
838 sun_contribution *= 1.0f + slope * diff;
839 }
840 else {
841 float diff = angular_diameter - 1.0f / 180.0f * M_PI_F;
842 float slope = (0.45f - 0.8f) / (third_point - second_point);
843 sun_contribution *= 0.8f + slope * diff;
844 }
845
846 return sun_contribution;
847}
848
850{
851 NodeType *type = NodeType::add("sky_texture", create, NodeType::SHADER);
852
854
855 static NodeEnum type_enum;
856 type_enum.insert("preetham", NODE_SKY_PREETHAM);
857 type_enum.insert("hosek_wilkie", NODE_SKY_HOSEK);
858 type_enum.insert("nishita_improved", NODE_SKY_NISHITA);
859 SOCKET_ENUM(sky_type, "Type", type_enum, NODE_SKY_NISHITA);
860
861 SOCKET_VECTOR(sun_direction, "Sun Direction", make_float3(0.0f, 0.0f, 1.0f));
862 SOCKET_FLOAT(turbidity, "Turbidity", 2.2f);
863 SOCKET_FLOAT(ground_albedo, "Ground Albedo", 0.3f);
864 SOCKET_BOOLEAN(sun_disc, "Sun Disc", true);
865 SOCKET_FLOAT(sun_size, "Sun Size", 0.009512f);
866 SOCKET_FLOAT(sun_intensity, "Sun Intensity", 1.0f);
867 SOCKET_FLOAT(sun_elevation, "Sun Elevation", 15.0f * M_PI_F / 180.0f);
868 SOCKET_FLOAT(sun_rotation, "Sun Rotation", 0.0f);
869 SOCKET_FLOAT(altitude, "Altitude", 1.0f);
870 SOCKET_FLOAT(air_density, "Air", 1.0f);
871 SOCKET_FLOAT(dust_density, "Dust", 1.0f);
872 SOCKET_FLOAT(ozone_density, "Ozone", 1.0f);
873
875
876 SOCKET_OUT_COLOR(color, "Color");
877
878 return type;
879}
880
881SkyTextureNode::SkyTextureNode() : TextureNode(get_node_type()) {}
882
884{
885 /* Patch sun position so users are able to animate the daylight cycle while keeping the shading
886 * code simple. */
887 float new_sun_elevation = sun_elevation;
888 float new_sun_rotation = sun_rotation;
889
890 /* Wrap `new_sun_elevation` into [-2PI..2PI] range. */
891 new_sun_elevation = fmodf(new_sun_elevation, M_2PI_F);
892 /* Wrap `new_sun_elevation` into [-PI..PI] range. */
893 if (fabsf(new_sun_elevation) >= M_PI_F) {
894 new_sun_elevation -= copysignf(2.0f, new_sun_elevation) * M_PI_F;
895 }
896 /* Wrap `new_sun_elevation` into [-PI/2..PI/2] range while keeping the same absolute position. */
897 if (new_sun_elevation >= M_PI_2_F || new_sun_elevation <= -M_PI_2_F) {
898 new_sun_elevation = copysignf(M_PI_F, new_sun_elevation) - new_sun_elevation;
899 new_sun_rotation += M_PI_F;
900 }
901
902 /* Wrap `new_sun_rotation` into [-2PI..2PI] range. */
903 new_sun_rotation = fmodf(new_sun_rotation, M_2PI_F);
904 /* Wrap `new_sun_rotation` into [0..2PI] range. */
905 if (new_sun_rotation < 0.0f) {
906 new_sun_rotation += M_2PI_F;
907 }
908 new_sun_rotation = M_2PI_F - new_sun_rotation;
909
910 sun_elevation = new_sun_elevation;
911 sun_rotation = new_sun_rotation;
912}
913
915{
916 ShaderInput *vector_in = input("Vector");
917 ShaderOutput *color_out = output("Color");
918
919 SunSky sunsky;
920 if (sky_type == NODE_SKY_PREETHAM) {
921 sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
922 }
923 else if (sky_type == NODE_SKY_HOSEK) {
924 sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
925 }
926 else if (sky_type == NODE_SKY_NISHITA) {
927 /* Clamp altitude to reasonable values.
928 * Below 1m causes numerical issues and above 60km is space. */
929 float clamped_altitude = clamp(altitude, 1.0f, 59999.0f);
930
932 sun_disc,
933 get_sun_size(),
934 sun_intensity,
935 sun_elevation,
936 sun_rotation,
937 clamped_altitude,
938 air_density,
939 dust_density);
940 /* precomputed texture image parameters */
941 ImageManager *image_manager = compiler.scene->image_manager;
942 ImageParams impar;
945
946 /* precompute sky texture */
947 if (handle.empty()) {
948 SkyLoader *loader = new SkyLoader(
949 sun_elevation, clamped_altitude, air_density, dust_density, ozone_density);
950 handle = image_manager->add_image(loader, impar);
951 }
952 }
953 else {
954 assert(false);
955 }
956
957 int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
958
959 compiler.stack_assign(color_out);
960 compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), sky_type);
961 /* nishita doesn't need this data */
962 if (sky_type != NODE_SKY_NISHITA) {
963 compiler.add_node(__float_as_uint(sunsky.phi),
964 __float_as_uint(sunsky.theta),
967 compiler.add_node(__float_as_uint(sunsky.radiance_z),
968 __float_as_uint(sunsky.config_x[0]),
969 __float_as_uint(sunsky.config_x[1]),
970 __float_as_uint(sunsky.config_x[2]));
971 compiler.add_node(__float_as_uint(sunsky.config_x[3]),
972 __float_as_uint(sunsky.config_x[4]),
973 __float_as_uint(sunsky.config_x[5]),
974 __float_as_uint(sunsky.config_x[6]));
975 compiler.add_node(__float_as_uint(sunsky.config_x[7]),
976 __float_as_uint(sunsky.config_x[8]),
977 __float_as_uint(sunsky.config_y[0]),
978 __float_as_uint(sunsky.config_y[1]));
979 compiler.add_node(__float_as_uint(sunsky.config_y[2]),
980 __float_as_uint(sunsky.config_y[3]),
981 __float_as_uint(sunsky.config_y[4]),
982 __float_as_uint(sunsky.config_y[5]));
983 compiler.add_node(__float_as_uint(sunsky.config_y[6]),
984 __float_as_uint(sunsky.config_y[7]),
985 __float_as_uint(sunsky.config_y[8]),
986 __float_as_uint(sunsky.config_z[0]));
987 compiler.add_node(__float_as_uint(sunsky.config_z[1]),
988 __float_as_uint(sunsky.config_z[2]),
989 __float_as_uint(sunsky.config_z[3]),
990 __float_as_uint(sunsky.config_z[4]));
991 compiler.add_node(__float_as_uint(sunsky.config_z[5]),
992 __float_as_uint(sunsky.config_z[6]),
993 __float_as_uint(sunsky.config_z[7]),
994 __float_as_uint(sunsky.config_z[8]));
995 }
996 else {
997 compiler.add_node(__float_as_uint(sunsky.nishita_data[0]),
998 __float_as_uint(sunsky.nishita_data[1]),
999 __float_as_uint(sunsky.nishita_data[2]),
1000 __float_as_uint(sunsky.nishita_data[3]));
1001 compiler.add_node(__float_as_uint(sunsky.nishita_data[4]),
1002 __float_as_uint(sunsky.nishita_data[5]),
1003 __float_as_uint(sunsky.nishita_data[6]),
1004 __float_as_uint(sunsky.nishita_data[7]));
1005 compiler.add_node(__float_as_uint(sunsky.nishita_data[8]),
1006 __float_as_uint(sunsky.nishita_data[9]),
1007 handle.svm_slot(),
1008 0);
1009 }
1010
1011 tex_mapping.compile_end(compiler, vector_in, vector_offset);
1012}
1013
1015{
1016 tex_mapping.compile(compiler);
1017
1018 SunSky sunsky;
1019 if (sky_type == NODE_SKY_PREETHAM) {
1020 sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
1021 }
1022 else if (sky_type == NODE_SKY_HOSEK) {
1023 sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
1024 }
1025 else if (sky_type == NODE_SKY_NISHITA) {
1026 /* Clamp altitude to reasonable values.
1027 * Below 1m causes numerical issues and above 60km is space. */
1028 float clamped_altitude = clamp(altitude, 1.0f, 59999.0f);
1029
1031 sun_disc,
1032 get_sun_size(),
1033 sun_intensity,
1034 sun_elevation,
1035 sun_rotation,
1036 clamped_altitude,
1037 air_density,
1038 dust_density);
1039 /* precomputed texture image parameters */
1040 ImageManager *image_manager = compiler.scene->image_manager;
1041 ImageParams impar;
1044
1045 /* precompute sky texture */
1046 if (handle.empty()) {
1047 SkyLoader *loader = new SkyLoader(
1048 sun_elevation, clamped_altitude, air_density, dust_density, ozone_density);
1049 handle = image_manager->add_image(loader, impar);
1050 }
1051 }
1052 else {
1053 assert(false);
1054 }
1055
1056 compiler.parameter(this, "sky_type");
1057 compiler.parameter("theta", sunsky.theta);
1058 compiler.parameter("phi", sunsky.phi);
1059 compiler.parameter_color("radiance",
1060 make_float3(sunsky.radiance_x, sunsky.radiance_y, sunsky.radiance_z));
1061 compiler.parameter_array("config_x", sunsky.config_x, 9);
1062 compiler.parameter_array("config_y", sunsky.config_y, 9);
1063 compiler.parameter_array("config_z", sunsky.config_z, 9);
1064 compiler.parameter_array("nishita_data", sunsky.nishita_data, 10);
1065 /* nishita texture */
1066 if (sky_type == NODE_SKY_NISHITA) {
1067 compiler.parameter_texture("filename", handle);
1068 }
1069 compiler.add(this, "node_sky_texture");
1070}
1071
1072/* Gradient Texture */
1073
1075{
1076 NodeType *type = NodeType::add("gradient_texture", create, NodeType::SHADER);
1077
1079
1080 static NodeEnum type_enum;
1081 type_enum.insert("linear", NODE_BLEND_LINEAR);
1082 type_enum.insert("quadratic", NODE_BLEND_QUADRATIC);
1083 type_enum.insert("easing", NODE_BLEND_EASING);
1084 type_enum.insert("diagonal", NODE_BLEND_DIAGONAL);
1085 type_enum.insert("radial", NODE_BLEND_RADIAL);
1086 type_enum.insert("quadratic_sphere", NODE_BLEND_QUADRATIC_SPHERE);
1087 type_enum.insert("spherical", NODE_BLEND_SPHERICAL);
1088 SOCKET_ENUM(gradient_type, "Type", type_enum, NODE_BLEND_LINEAR);
1089
1091
1092 SOCKET_OUT_COLOR(color, "Color");
1093 SOCKET_OUT_FLOAT(fac, "Fac");
1094
1095 return type;
1096}
1097
1098GradientTextureNode::GradientTextureNode() : TextureNode(get_node_type()) {}
1099
1101{
1102 ShaderInput *vector_in = input("Vector");
1103 ShaderOutput *color_out = output("Color");
1104 ShaderOutput *fac_out = output("Fac");
1105
1106 int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1107
1108 compiler.add_node(NODE_TEX_GRADIENT,
1109 compiler.encode_uchar4(gradient_type,
1110 vector_offset,
1111 compiler.stack_assign_if_linked(fac_out),
1112 compiler.stack_assign_if_linked(color_out)));
1113
1114 tex_mapping.compile_end(compiler, vector_in, vector_offset);
1115}
1116
1118{
1119 tex_mapping.compile(compiler);
1120
1121 compiler.parameter(this, "gradient_type");
1122 compiler.add(this, "node_gradient_texture");
1123}
1124
1125/* Noise Texture */
1126
1128{
1129 NodeType *type = NodeType::add("noise_texture", create, NodeType::SHADER);
1130
1132
1133 static NodeEnum dimensions_enum;
1134 dimensions_enum.insert("1D", 1);
1135 dimensions_enum.insert("2D", 2);
1136 dimensions_enum.insert("3D", 3);
1137 dimensions_enum.insert("4D", 4);
1138 SOCKET_ENUM(dimensions, "Dimensions", dimensions_enum, 3);
1139
1140 static NodeEnum type_enum;
1141 type_enum.insert("multifractal", NODE_NOISE_MULTIFRACTAL);
1142 type_enum.insert("fBM", NODE_NOISE_FBM);
1143 type_enum.insert("hybrid_multifractal", NODE_NOISE_HYBRID_MULTIFRACTAL);
1144 type_enum.insert("ridged_multifractal", NODE_NOISE_RIDGED_MULTIFRACTAL);
1145 type_enum.insert("hetero_terrain", NODE_NOISE_HETERO_TERRAIN);
1146 SOCKET_ENUM(type, "Type", type_enum, NODE_NOISE_FBM);
1147
1148 SOCKET_BOOLEAN(use_normalize, "Normalize", true);
1149
1151 SOCKET_IN_FLOAT(w, "W", 0.0f);
1152 SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
1153 SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
1154 SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
1155 SOCKET_IN_FLOAT(lacunarity, "Lacunarity", 2.0f);
1156 SOCKET_IN_FLOAT(offset, "Offset", 0.0f);
1157 SOCKET_IN_FLOAT(gain, "Gain", 1.0f);
1158 SOCKET_IN_FLOAT(distortion, "Distortion", 0.0f);
1159
1160 SOCKET_OUT_FLOAT(fac, "Fac");
1161 SOCKET_OUT_COLOR(color, "Color");
1162
1163 return type;
1164}
1165
1166NoiseTextureNode::NoiseTextureNode() : TextureNode(get_node_type()) {}
1167
1169{
1170 ShaderInput *vector_in = input("Vector");
1171 ShaderInput *w_in = input("W");
1172 ShaderInput *scale_in = input("Scale");
1173 ShaderInput *detail_in = input("Detail");
1174 ShaderInput *roughness_in = input("Roughness");
1175 ShaderInput *lacunarity_in = input("Lacunarity");
1176 ShaderInput *offset_in = input("Offset");
1177 ShaderInput *gain_in = input("Gain");
1178 ShaderInput *distortion_in = input("Distortion");
1179 ShaderOutput *fac_out = output("Fac");
1180 ShaderOutput *color_out = output("Color");
1181
1182 int vector_stack_offset = tex_mapping.compile_begin(compiler, vector_in);
1183 int w_stack_offset = compiler.stack_assign_if_linked(w_in);
1184 int scale_stack_offset = compiler.stack_assign_if_linked(scale_in);
1185 int detail_stack_offset = compiler.stack_assign_if_linked(detail_in);
1186 int roughness_stack_offset = compiler.stack_assign_if_linked(roughness_in);
1187 int lacunarity_stack_offset = compiler.stack_assign_if_linked(lacunarity_in);
1188 int offset_stack_offset = compiler.stack_assign_if_linked(offset_in);
1189 int gain_stack_offset = compiler.stack_assign_if_linked(gain_in);
1190 int distortion_stack_offset = compiler.stack_assign_if_linked(distortion_in);
1191 int fac_stack_offset = compiler.stack_assign_if_linked(fac_out);
1192 int color_stack_offset = compiler.stack_assign_if_linked(color_out);
1193
1194 compiler.add_node(
1195 NODE_TEX_NOISE,
1196 compiler.encode_uchar4(
1197 vector_stack_offset, w_stack_offset, scale_stack_offset, detail_stack_offset),
1198 compiler.encode_uchar4(
1199 roughness_stack_offset, lacunarity_stack_offset, offset_stack_offset, gain_stack_offset),
1200 compiler.encode_uchar4(distortion_stack_offset, fac_stack_offset, color_stack_offset));
1201
1202 compiler.add_node(
1203 __float_as_int(w), __float_as_int(scale), __float_as_int(detail), __float_as_int(roughness));
1204
1205 compiler.add_node(__float_as_int(lacunarity),
1206 __float_as_int(offset),
1207 __float_as_int(gain),
1208 __float_as_int(distortion));
1209 compiler.add_node(dimensions, type, use_normalize, SVM_STACK_INVALID);
1210
1211 tex_mapping.compile_end(compiler, vector_in, vector_stack_offset);
1212}
1213
1215{
1216 tex_mapping.compile(compiler);
1217 compiler.parameter(this, "dimensions");
1218 compiler.parameter(this, "type");
1219 compiler.parameter(this, "use_normalize");
1220 compiler.add(this, "node_noise_texture");
1221}
1222
1223/* Gabor Texture */
1224
1226{
1227 NodeType *type = NodeType::add("gabor_texture", create, NodeType::SHADER);
1228
1230
1231 static NodeEnum type_enum;
1232 type_enum.insert("2D", NODE_GABOR_TYPE_2D);
1233 type_enum.insert("3D", NODE_GABOR_TYPE_3D);
1234 SOCKET_ENUM(type, "Type", type_enum, NODE_GABOR_TYPE_2D);
1235
1237 SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
1238 SOCKET_IN_FLOAT(frequency, "Frequency", 2.0f);
1239 SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 1.0f);
1240 SOCKET_IN_FLOAT(orientation_2d, "Orientation 2D", M_PI_F / 4.0f);
1241 SOCKET_IN_VECTOR(orientation_3d, "Orientation 3D", make_float3(M_SQRT2_F, M_SQRT2_F, 0.0f));
1242
1243 SOCKET_OUT_FLOAT(value, "Value");
1244 SOCKET_OUT_FLOAT(phase, "Phase");
1245 SOCKET_OUT_FLOAT(intensity, "Intensity");
1246
1247 return type;
1248}
1249
1250GaborTextureNode::GaborTextureNode() : TextureNode(get_node_type()) {}
1251
1253{
1254 ShaderInput *vector_in = input("Vector");
1255 ShaderInput *scale_in = input("Scale");
1256 ShaderInput *frequency_in = input("Frequency");
1257 ShaderInput *anisotropy_in = input("Anisotropy");
1258 ShaderInput *orientation_2d_in = input("Orientation 2D");
1259 ShaderInput *orientation_3d_in = input("Orientation 3D");
1260
1261 ShaderOutput *value_out = output("Value");
1262 ShaderOutput *phase_out = output("Phase");
1263 ShaderOutput *intensity_out = output("Intensity");
1264
1265 int vector_stack_offset = tex_mapping.compile_begin(compiler, vector_in);
1266 int scale_stack_offset = compiler.stack_assign_if_linked(scale_in);
1267 int frequency_stack_offset = compiler.stack_assign_if_linked(frequency_in);
1268 int anisotropy_stack_offset = compiler.stack_assign_if_linked(anisotropy_in);
1269 int orientation_2d_stack_offset = compiler.stack_assign_if_linked(orientation_2d_in);
1270 int orientation_3d_stack_offset = compiler.stack_assign(orientation_3d_in);
1271
1272 int value_stack_offset = compiler.stack_assign_if_linked(value_out);
1273 int phase_stack_offset = compiler.stack_assign_if_linked(phase_out);
1274 int intensity_stack_offset = compiler.stack_assign_if_linked(intensity_out);
1275
1276 compiler.add_node(
1277 NODE_TEX_GABOR,
1278 type,
1279 compiler.encode_uchar4(vector_stack_offset,
1280 scale_stack_offset,
1281 frequency_stack_offset,
1282 anisotropy_stack_offset),
1283 compiler.encode_uchar4(orientation_2d_stack_offset, orientation_3d_stack_offset));
1284
1285 compiler.add_node(
1286 compiler.encode_uchar4(value_stack_offset, phase_stack_offset, intensity_stack_offset),
1287 __float_as_int(scale),
1288 __float_as_int(frequency),
1289 __float_as_int(anisotropy));
1290 compiler.add_node(__float_as_int(orientation_2d));
1291
1292 tex_mapping.compile_end(compiler, vector_in, vector_stack_offset);
1293}
1294
1296{
1297 tex_mapping.compile(compiler);
1298 compiler.parameter(this, "type");
1299 compiler.add(this, "node_gabor_texture");
1300}
1301
1302/* Voronoi Texture */
1303
1305{
1306 NodeType *type = NodeType::add("voronoi_texture", create, NodeType::SHADER);
1307
1309
1310 static NodeEnum dimensions_enum;
1311 dimensions_enum.insert("1D", 1);
1312 dimensions_enum.insert("2D", 2);
1313 dimensions_enum.insert("3D", 3);
1314 dimensions_enum.insert("4D", 4);
1315 SOCKET_ENUM(dimensions, "Dimensions", dimensions_enum, 3);
1316
1317 static NodeEnum metric_enum;
1318 metric_enum.insert("euclidean", NODE_VORONOI_EUCLIDEAN);
1319 metric_enum.insert("manhattan", NODE_VORONOI_MANHATTAN);
1320 metric_enum.insert("chebychev", NODE_VORONOI_CHEBYCHEV);
1321 metric_enum.insert("minkowski", NODE_VORONOI_MINKOWSKI);
1322 SOCKET_ENUM(metric, "Distance Metric", metric_enum, NODE_VORONOI_EUCLIDEAN);
1323
1324 static NodeEnum feature_enum;
1325 feature_enum.insert("f1", NODE_VORONOI_F1);
1326 feature_enum.insert("f2", NODE_VORONOI_F2);
1327 feature_enum.insert("smooth_f1", NODE_VORONOI_SMOOTH_F1);
1328 feature_enum.insert("distance_to_edge", NODE_VORONOI_DISTANCE_TO_EDGE);
1329 feature_enum.insert("n_sphere_radius", NODE_VORONOI_N_SPHERE_RADIUS);
1330 SOCKET_ENUM(feature, "Feature", feature_enum, NODE_VORONOI_F1);
1331
1332 SOCKET_BOOLEAN(use_normalize, "Normalize", false);
1333
1335 SOCKET_IN_FLOAT(w, "W", 0.0f);
1336 SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
1337 SOCKET_IN_FLOAT(detail, "Detail", 0.0f);
1338 SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
1339 SOCKET_IN_FLOAT(lacunarity, "Lacunarity", 2.0f);
1340 SOCKET_IN_FLOAT(smoothness, "Smoothness", 5.0f);
1341 SOCKET_IN_FLOAT(exponent, "Exponent", 0.5f);
1342 SOCKET_IN_FLOAT(randomness, "Randomness", 1.0f);
1343
1344 SOCKET_OUT_FLOAT(distance, "Distance");
1345 SOCKET_OUT_COLOR(color, "Color");
1346 SOCKET_OUT_POINT(position, "Position");
1347 SOCKET_OUT_FLOAT(w, "W");
1348 SOCKET_OUT_FLOAT(radius, "Radius");
1349
1350 return type;
1351}
1352
1353VoronoiTextureNode::VoronoiTextureNode() : TextureNode(get_node_type()) {}
1354
1356{
1357 ShaderInput *vector_in = input("Vector");
1358 ShaderInput *w_in = input("W");
1359 ShaderInput *scale_in = input("Scale");
1360 ShaderInput *detail_in = input("Detail");
1361 ShaderInput *roughness_in = input("Roughness");
1362 ShaderInput *lacunarity_in = input("Lacunarity");
1363 ShaderInput *smoothness_in = input("Smoothness");
1364 ShaderInput *exponent_in = input("Exponent");
1365 ShaderInput *randomness_in = input("Randomness");
1366
1367 ShaderOutput *distance_out = output("Distance");
1368 ShaderOutput *color_out = output("Color");
1369 ShaderOutput *position_out = output("Position");
1370 ShaderOutput *w_out = output("W");
1371 ShaderOutput *radius_out = output("Radius");
1372
1373 int vector_stack_offset = tex_mapping.compile_begin(compiler, vector_in);
1374 int w_in_stack_offset = compiler.stack_assign_if_linked(w_in);
1375 int scale_stack_offset = compiler.stack_assign_if_linked(scale_in);
1376 int detail_stack_offset = compiler.stack_assign_if_linked(detail_in);
1377 int roughness_stack_offset = compiler.stack_assign_if_linked(roughness_in);
1378 int lacunarity_stack_offset = compiler.stack_assign_if_linked(lacunarity_in);
1379 int smoothness_stack_offset = compiler.stack_assign_if_linked(smoothness_in);
1380 int exponent_stack_offset = compiler.stack_assign_if_linked(exponent_in);
1381 int randomness_stack_offset = compiler.stack_assign_if_linked(randomness_in);
1382 int distance_stack_offset = compiler.stack_assign_if_linked(distance_out);
1383 int color_stack_offset = compiler.stack_assign_if_linked(color_out);
1384 int position_stack_offset = compiler.stack_assign_if_linked(position_out);
1385 int w_out_stack_offset = compiler.stack_assign_if_linked(w_out);
1386 int radius_stack_offset = compiler.stack_assign_if_linked(radius_out);
1387
1388 compiler.add_node(NODE_TEX_VORONOI, dimensions, feature, metric);
1389 compiler.add_node(
1390 compiler.encode_uchar4(
1391 vector_stack_offset, w_in_stack_offset, scale_stack_offset, detail_stack_offset),
1392 compiler.encode_uchar4(roughness_stack_offset,
1393 lacunarity_stack_offset,
1394 smoothness_stack_offset,
1395 exponent_stack_offset),
1396 compiler.encode_uchar4(
1397 randomness_stack_offset, use_normalize, distance_stack_offset, color_stack_offset),
1398 compiler.encode_uchar4(position_stack_offset, w_out_stack_offset, radius_stack_offset));
1399
1400 compiler.add_node(
1401 __float_as_int(w), __float_as_int(scale), __float_as_int(detail), __float_as_int(roughness));
1402 compiler.add_node(__float_as_int(lacunarity),
1403 __float_as_int(smoothness),
1404 __float_as_int(exponent),
1405 __float_as_int(randomness));
1406 tex_mapping.compile_end(compiler, vector_in, vector_stack_offset);
1407}
1408
1410{
1411 tex_mapping.compile(compiler);
1412
1413 compiler.parameter(this, "dimensions");
1414 compiler.parameter(this, "feature");
1415 compiler.parameter(this, "metric");
1416 compiler.parameter(this, "use_normalize");
1417 compiler.add(this, "node_voronoi_texture");
1418}
1419
1420/* IES Light */
1421
1423{
1424 NodeType *type = NodeType::add("ies_light", create, NodeType::SHADER);
1425
1427
1428 SOCKET_STRING(ies, "IES", ustring());
1429 SOCKET_STRING(filename, "File Name", ustring());
1430
1431 SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
1433
1434 SOCKET_OUT_FLOAT(fac, "Fac");
1435
1436 return type;
1437}
1438
1439IESLightNode::IESLightNode() : TextureNode(get_node_type())
1440{
1441 light_manager = NULL;
1442 slot = -1;
1443}
1444
1446{
1447 IESLightNode *node = graph->create_node<IESLightNode>(*this);
1448
1449 node->light_manager = NULL;
1450 node->slot = -1;
1451
1452 return node;
1453}
1454
1456{
1457 if (light_manager) {
1458 light_manager->remove_ies(slot);
1459 }
1460}
1461
1462void IESLightNode::get_slot()
1463{
1464 assert(light_manager);
1465
1466 if (slot == -1) {
1467 if (ies.empty()) {
1468 slot = light_manager->add_ies_from_file(filename.string());
1469 }
1470 else {
1471 slot = light_manager->add_ies(ies.string());
1472 }
1473 }
1474}
1475
1476void IESLightNode::compile(SVMCompiler &compiler)
1477{
1478 light_manager = compiler.scene->light_manager;
1479 get_slot();
1480
1481 ShaderInput *strength_in = input("Strength");
1482 ShaderInput *vector_in = input("Vector");
1483 ShaderOutput *fac_out = output("Fac");
1484
1485 int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1486
1487 compiler.add_node(NODE_IES,
1488 compiler.encode_uchar4(compiler.stack_assign_if_linked(strength_in),
1489 vector_offset,
1490 compiler.stack_assign(fac_out),
1491 0),
1492 slot,
1493 __float_as_int(strength));
1494
1495 tex_mapping.compile_end(compiler, vector_in, vector_offset);
1496}
1497
1498void IESLightNode::compile(OSLCompiler &compiler)
1499{
1500 light_manager = compiler.scene->light_manager;
1501 get_slot();
1502
1503 tex_mapping.compile(compiler);
1504
1505 compiler.parameter_texture_ies("filename", slot);
1506 compiler.add(this, "node_ies_light");
1507}
1508
1509/* White Noise Texture */
1510
1512{
1513 NodeType *type = NodeType::add("white_noise_texture", create, NodeType::SHADER);
1514
1515 static NodeEnum dimensions_enum;
1516 dimensions_enum.insert("1D", 1);
1517 dimensions_enum.insert("2D", 2);
1518 dimensions_enum.insert("3D", 3);
1519 dimensions_enum.insert("4D", 4);
1520 SOCKET_ENUM(dimensions, "Dimensions", dimensions_enum, 3);
1521
1522 SOCKET_IN_POINT(vector, "Vector", zero_float3());
1523 SOCKET_IN_FLOAT(w, "W", 0.0f);
1524
1525 SOCKET_OUT_FLOAT(value, "Value");
1526 SOCKET_OUT_COLOR(color, "Color");
1527
1528 return type;
1529}
1530
1531WhiteNoiseTextureNode::WhiteNoiseTextureNode() : ShaderNode(get_node_type()) {}
1532
1534{
1535 ShaderInput *vector_in = input("Vector");
1536 ShaderInput *w_in = input("W");
1537 ShaderOutput *value_out = output("Value");
1538 ShaderOutput *color_out = output("Color");
1539
1540 int vector_stack_offset = compiler.stack_assign(vector_in);
1541 int w_stack_offset = compiler.stack_assign(w_in);
1542 int value_stack_offset = compiler.stack_assign(value_out);
1543 int color_stack_offset = compiler.stack_assign(color_out);
1544
1545 compiler.add_node(NODE_TEX_WHITE_NOISE,
1546 dimensions,
1547 compiler.encode_uchar4(vector_stack_offset, w_stack_offset),
1548 compiler.encode_uchar4(value_stack_offset, color_stack_offset));
1549}
1550
1552{
1553 compiler.parameter(this, "dimensions");
1554 compiler.add(this, "node_white_noise_texture");
1555}
1556
1557/* Wave Texture */
1558
1560{
1561 NodeType *type = NodeType::add("wave_texture", create, NodeType::SHADER);
1562
1564
1565 static NodeEnum type_enum;
1566 type_enum.insert("bands", NODE_WAVE_BANDS);
1567 type_enum.insert("rings", NODE_WAVE_RINGS);
1568 SOCKET_ENUM(wave_type, "Type", type_enum, NODE_WAVE_BANDS);
1569
1570 static NodeEnum bands_direction_enum;
1571 bands_direction_enum.insert("x", NODE_WAVE_BANDS_DIRECTION_X);
1572 bands_direction_enum.insert("y", NODE_WAVE_BANDS_DIRECTION_Y);
1573 bands_direction_enum.insert("z", NODE_WAVE_BANDS_DIRECTION_Z);
1574 bands_direction_enum.insert("diagonal", NODE_WAVE_BANDS_DIRECTION_DIAGONAL);
1576 bands_direction, "Bands Direction", bands_direction_enum, NODE_WAVE_BANDS_DIRECTION_X);
1577
1578 static NodeEnum rings_direction_enum;
1579 rings_direction_enum.insert("x", NODE_WAVE_RINGS_DIRECTION_X);
1580 rings_direction_enum.insert("y", NODE_WAVE_RINGS_DIRECTION_Y);
1581 rings_direction_enum.insert("z", NODE_WAVE_RINGS_DIRECTION_Z);
1582 rings_direction_enum.insert("spherical", NODE_WAVE_RINGS_DIRECTION_SPHERICAL);
1584 rings_direction, "Rings Direction", rings_direction_enum, NODE_WAVE_BANDS_DIRECTION_X);
1585
1586 static NodeEnum profile_enum;
1587 profile_enum.insert("sine", NODE_WAVE_PROFILE_SIN);
1588 profile_enum.insert("saw", NODE_WAVE_PROFILE_SAW);
1589 profile_enum.insert("tri", NODE_WAVE_PROFILE_TRI);
1590 SOCKET_ENUM(profile, "Profile", profile_enum, NODE_WAVE_PROFILE_SIN);
1591
1593 SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
1594 SOCKET_IN_FLOAT(distortion, "Distortion", 0.0f);
1595 SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
1596 SOCKET_IN_FLOAT(detail_scale, "Detail Scale", 0.0f);
1597 SOCKET_IN_FLOAT(detail_roughness, "Detail Roughness", 0.5f);
1598 SOCKET_IN_FLOAT(phase, "Phase Offset", 0.0f);
1599 SOCKET_OUT_COLOR(color, "Color");
1600 SOCKET_OUT_FLOAT(fac, "Fac");
1601
1602 return type;
1603}
1604
1605WaveTextureNode::WaveTextureNode() : TextureNode(get_node_type()) {}
1606
1608{
1609 ShaderInput *vector_in = input("Vector");
1610 ShaderInput *scale_in = input("Scale");
1611 ShaderInput *distortion_in = input("Distortion");
1612 ShaderInput *detail_in = input("Detail");
1613 ShaderInput *dscale_in = input("Detail Scale");
1614 ShaderInput *droughness_in = input("Detail Roughness");
1615 ShaderInput *phase_in = input("Phase Offset");
1616 ShaderOutput *color_out = output("Color");
1617 ShaderOutput *fac_out = output("Fac");
1618
1619 int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1620
1621 int scale_ofs = compiler.stack_assign_if_linked(scale_in);
1622 int distortion_ofs = compiler.stack_assign_if_linked(distortion_in);
1623 int detail_ofs = compiler.stack_assign_if_linked(detail_in);
1624 int dscale_ofs = compiler.stack_assign_if_linked(dscale_in);
1625 int droughness_ofs = compiler.stack_assign_if_linked(droughness_in);
1626 int phase_ofs = compiler.stack_assign_if_linked(phase_in);
1627 int color_ofs = compiler.stack_assign_if_linked(color_out);
1628 int fac_ofs = compiler.stack_assign_if_linked(fac_out);
1629
1630 compiler.add_node(NODE_TEX_WAVE,
1631 compiler.encode_uchar4(wave_type, bands_direction, rings_direction, profile),
1632 compiler.encode_uchar4(vector_offset, scale_ofs, distortion_ofs),
1633 compiler.encode_uchar4(detail_ofs, dscale_ofs, droughness_ofs, phase_ofs));
1634
1635 compiler.add_node(compiler.encode_uchar4(color_ofs, fac_ofs),
1636 __float_as_int(scale),
1637 __float_as_int(distortion),
1638 __float_as_int(detail));
1639
1640 compiler.add_node(__float_as_int(detail_scale),
1641 __float_as_int(detail_roughness),
1642 __float_as_int(phase),
1644
1645 tex_mapping.compile_end(compiler, vector_in, vector_offset);
1646}
1647
1649{
1650 tex_mapping.compile(compiler);
1651
1652 compiler.parameter(this, "wave_type");
1653 compiler.parameter(this, "bands_direction");
1654 compiler.parameter(this, "rings_direction");
1655 compiler.parameter(this, "profile");
1656
1657 compiler.add(this, "node_wave_texture");
1658}
1659
1660/* Magic Texture */
1661
1663{
1664 NodeType *type = NodeType::add("magic_texture", create, NodeType::SHADER);
1665
1667
1668 SOCKET_INT(depth, "Depth", 2);
1669
1671 SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
1672 SOCKET_IN_FLOAT(distortion, "Distortion", 1.0f);
1673
1674 SOCKET_OUT_COLOR(color, "Color");
1675 SOCKET_OUT_FLOAT(fac, "Fac");
1676
1677 return type;
1678}
1679
1680MagicTextureNode::MagicTextureNode() : TextureNode(get_node_type()) {}
1681
1683{
1684 ShaderInput *vector_in = input("Vector");
1685 ShaderInput *scale_in = input("Scale");
1686 ShaderInput *distortion_in = input("Distortion");
1687 ShaderOutput *color_out = output("Color");
1688 ShaderOutput *fac_out = output("Fac");
1689
1690 int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1691
1692 compiler.add_node(NODE_TEX_MAGIC,
1693 compiler.encode_uchar4(depth,
1694 compiler.stack_assign_if_linked(color_out),
1695 compiler.stack_assign_if_linked(fac_out)),
1696 compiler.encode_uchar4(vector_offset,
1697 compiler.stack_assign_if_linked(scale_in),
1698 compiler.stack_assign_if_linked(distortion_in)));
1699 compiler.add_node(__float_as_int(scale), __float_as_int(distortion));
1700
1701 tex_mapping.compile_end(compiler, vector_in, vector_offset);
1702}
1703
1705{
1706 tex_mapping.compile(compiler);
1707
1708 compiler.parameter(this, "depth");
1709 compiler.add(this, "node_magic_texture");
1710}
1711
1712/* Checker Texture */
1713
1715{
1716 NodeType *type = NodeType::add("checker_texture", create, NodeType::SHADER);
1717
1719
1721 SOCKET_IN_COLOR(color1, "Color1", zero_float3());
1722 SOCKET_IN_COLOR(color2, "Color2", zero_float3());
1723 SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
1724
1725 SOCKET_OUT_COLOR(color, "Color");
1726 SOCKET_OUT_FLOAT(fac, "Fac");
1727
1728 return type;
1729}
1730
1731CheckerTextureNode::CheckerTextureNode() : TextureNode(get_node_type()) {}
1732
1734{
1735 ShaderInput *vector_in = input("Vector");
1736 ShaderInput *color1_in = input("Color1");
1737 ShaderInput *color2_in = input("Color2");
1738 ShaderInput *scale_in = input("Scale");
1739
1740 ShaderOutput *color_out = output("Color");
1741 ShaderOutput *fac_out = output("Fac");
1742
1743 int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1744
1745 compiler.add_node(NODE_TEX_CHECKER,
1746 compiler.encode_uchar4(vector_offset,
1747 compiler.stack_assign(color1_in),
1748 compiler.stack_assign(color2_in),
1749 compiler.stack_assign_if_linked(scale_in)),
1750 compiler.encode_uchar4(compiler.stack_assign_if_linked(color_out),
1751 compiler.stack_assign_if_linked(fac_out)),
1752 __float_as_int(scale));
1753
1754 tex_mapping.compile_end(compiler, vector_in, vector_offset);
1755}
1756
1758{
1759 tex_mapping.compile(compiler);
1760
1761 compiler.add(this, "node_checker_texture");
1762}
1763
1764/* Brick Texture */
1765
1767{
1768 NodeType *type = NodeType::add("brick_texture", create, NodeType::SHADER);
1769
1771
1772 SOCKET_FLOAT(offset, "Offset", 0.5f);
1773 SOCKET_INT(offset_frequency, "Offset Frequency", 2);
1774 SOCKET_FLOAT(squash, "Squash", 1.0f);
1775 SOCKET_INT(squash_frequency, "Squash Frequency", 2);
1776
1778
1779 SOCKET_IN_COLOR(color1, "Color1", zero_float3());
1780 SOCKET_IN_COLOR(color2, "Color2", zero_float3());
1781 SOCKET_IN_COLOR(mortar, "Mortar", zero_float3());
1782 SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
1783 SOCKET_IN_FLOAT(mortar_size, "Mortar Size", 0.02f);
1784 SOCKET_IN_FLOAT(mortar_smooth, "Mortar Smooth", 0.0f);
1785 SOCKET_IN_FLOAT(bias, "Bias", 0.0f);
1786 SOCKET_IN_FLOAT(brick_width, "Brick Width", 0.5f);
1787 SOCKET_IN_FLOAT(row_height, "Row Height", 0.25f);
1788
1789 SOCKET_OUT_COLOR(color, "Color");
1790 SOCKET_OUT_FLOAT(fac, "Fac");
1791
1792 return type;
1793}
1794
1795BrickTextureNode::BrickTextureNode() : TextureNode(get_node_type()) {}
1796
1798{
1799 ShaderInput *vector_in = input("Vector");
1800 ShaderInput *color1_in = input("Color1");
1801 ShaderInput *color2_in = input("Color2");
1802 ShaderInput *mortar_in = input("Mortar");
1803 ShaderInput *scale_in = input("Scale");
1804 ShaderInput *mortar_size_in = input("Mortar Size");
1805 ShaderInput *mortar_smooth_in = input("Mortar Smooth");
1806 ShaderInput *bias_in = input("Bias");
1807 ShaderInput *brick_width_in = input("Brick Width");
1808 ShaderInput *row_height_in = input("Row Height");
1809
1810 ShaderOutput *color_out = output("Color");
1811 ShaderOutput *fac_out = output("Fac");
1812
1813 int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1814
1815 compiler.add_node(NODE_TEX_BRICK,
1816 compiler.encode_uchar4(vector_offset,
1817 compiler.stack_assign(color1_in),
1818 compiler.stack_assign(color2_in),
1819 compiler.stack_assign(mortar_in)),
1820 compiler.encode_uchar4(compiler.stack_assign_if_linked(scale_in),
1821 compiler.stack_assign_if_linked(mortar_size_in),
1822 compiler.stack_assign_if_linked(bias_in),
1823 compiler.stack_assign_if_linked(brick_width_in)),
1824 compiler.encode_uchar4(compiler.stack_assign_if_linked(row_height_in),
1825 compiler.stack_assign_if_linked(color_out),
1826 compiler.stack_assign_if_linked(fac_out),
1827 compiler.stack_assign_if_linked(mortar_smooth_in)));
1828
1829 compiler.add_node(compiler.encode_uchar4(offset_frequency, squash_frequency),
1830 __float_as_int(scale),
1831 __float_as_int(mortar_size),
1832 __float_as_int(bias));
1833
1834 compiler.add_node(__float_as_int(brick_width),
1835 __float_as_int(row_height),
1836 __float_as_int(offset),
1837 __float_as_int(squash));
1838
1839 compiler.add_node(
1841
1842 tex_mapping.compile_end(compiler, vector_in, vector_offset);
1843}
1844
1846{
1847 tex_mapping.compile(compiler);
1848
1849 compiler.parameter(this, "offset");
1850 compiler.parameter(this, "offset_frequency");
1851 compiler.parameter(this, "squash");
1852 compiler.parameter(this, "squash_frequency");
1853 compiler.add(this, "node_brick_texture");
1854}
1855
1856/* Point Density Texture */
1857
1859{
1860 NodeType *type = NodeType::add("point_density_texture", create, NodeType::SHADER);
1861
1862 SOCKET_STRING(filename, "Filename", ustring());
1863
1864 static NodeEnum space_enum;
1865 space_enum.insert("object", NODE_TEX_VOXEL_SPACE_OBJECT);
1866 space_enum.insert("world", NODE_TEX_VOXEL_SPACE_WORLD);
1867 SOCKET_ENUM(space, "Space", space_enum, NODE_TEX_VOXEL_SPACE_OBJECT);
1868
1869 static NodeEnum interpolation_enum;
1870 interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
1871 interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
1872 interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
1873 interpolation_enum.insert("smart", INTERPOLATION_SMART);
1874 SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
1875
1876 SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
1877
1879
1880 SOCKET_OUT_FLOAT(density, "Density");
1881 SOCKET_OUT_COLOR(color, "Color");
1882
1883 return type;
1884}
1885
1886PointDensityTextureNode::PointDensityTextureNode() : ShaderNode(get_node_type()) {}
1887
1889
1891{
1892 /* Increase image user count for new node. We need to ensure to not call
1893 * add_image again, to work around access of freed data on the Blender
1894 * side. A better solution should be found to avoid this. */
1895 PointDensityTextureNode *node = graph->create_node<PointDensityTextureNode>(*this);
1896 node->handle = handle; /* TODO: not needed? */
1897 return node;
1898}
1899
1901{
1902 if (shader->has_volume) {
1903 attributes->add(ATTR_STD_GENERATED_TRANSFORM);
1904 }
1905
1906 ShaderNode::attributes(shader, attributes);
1907}
1908
1910{
1912 params.interpolation = interpolation;
1913 return params;
1914}
1915
1917{
1918 ShaderInput *vector_in = input("Vector");
1919 ShaderOutput *density_out = output("Density");
1920 ShaderOutput *color_out = output("Color");
1921
1922 const bool use_density = !density_out->links.empty();
1923 const bool use_color = !color_out->links.empty();
1924
1925 if (!(use_density || use_color)) {
1926 return;
1927 }
1928
1929 /* Point Density is only supported for volume shaders. */
1930 if (compiler.output_type() != SHADER_TYPE_VOLUME) {
1931 if (use_density) {
1932 compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(density_out));
1933 }
1934 if (use_color) {
1935 compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
1936 compiler.add_node(NODE_VALUE_V, zero_float3());
1937 }
1938 return;
1939 }
1940
1941 if (handle.empty()) {
1942 ImageManager *image_manager = compiler.scene->image_manager;
1943 handle = image_manager->add_image(filename.string(), image_params());
1944 }
1945
1946 const int slot = handle.svm_slot();
1947 if (slot != -1) {
1948 compiler.stack_assign(vector_in);
1949 compiler.add_node(NODE_TEX_VOXEL,
1950 slot,
1951 compiler.encode_uchar4(compiler.stack_assign(vector_in),
1952 compiler.stack_assign_if_linked(density_out),
1953 compiler.stack_assign_if_linked(color_out),
1954 space));
1955 if (space == NODE_TEX_VOXEL_SPACE_WORLD) {
1956 compiler.add_node(tfm.x);
1957 compiler.add_node(tfm.y);
1958 compiler.add_node(tfm.z);
1959 }
1960 }
1961 else {
1962 if (use_density) {
1963 compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(density_out));
1964 }
1965 if (use_color) {
1966 compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
1967 compiler.add_node(
1968 NODE_VALUE_V,
1970 }
1971 }
1972}
1973
1975{
1976 ShaderOutput *density_out = output("Density");
1977 ShaderOutput *color_out = output("Color");
1978
1979 const bool use_density = !density_out->links.empty();
1980 const bool use_color = !color_out->links.empty();
1981
1982 if (!(use_density || use_color)) {
1983 return;
1984 }
1985
1986 /* Point Density is only supported for volume shaders. */
1987 if (compiler.output_type() != SHADER_TYPE_VOLUME) {
1988 compiler.add(this, "node_voxel_texture_zero");
1989 return;
1990 }
1991
1992 if (handle.empty()) {
1993 ImageManager *image_manager = compiler.scene->image_manager;
1994 handle = image_manager->add_image(filename.string(), image_params());
1995 }
1996
1997 compiler.parameter_texture("filename", handle);
1998 if (space == NODE_TEX_VOXEL_SPACE_WORLD) {
1999 compiler.parameter("mapping", tfm);
2000 compiler.parameter("use_mapping", 1);
2001 }
2002 compiler.parameter(this, "interpolation");
2003 compiler.add(this, "node_voxel_texture");
2004}
2005
2006/* Normal */
2007
2009{
2010 NodeType *type = NodeType::add("normal", create, NodeType::SHADER);
2011
2012 SOCKET_VECTOR(direction, "direction", zero_float3());
2013
2014 SOCKET_IN_NORMAL(normal, "Normal", zero_float3());
2015
2016 SOCKET_OUT_NORMAL(normal, "Normal");
2017 SOCKET_OUT_FLOAT(dot, "Dot");
2018
2019 return type;
2020}
2021
2022NormalNode::NormalNode() : ShaderNode(get_node_type()) {}
2023
2024void NormalNode::compile(SVMCompiler &compiler)
2025{
2026 ShaderInput *normal_in = input("Normal");
2027 ShaderOutput *normal_out = output("Normal");
2028 ShaderOutput *dot_out = output("Dot");
2029
2030 compiler.add_node(NODE_NORMAL,
2031 compiler.stack_assign(normal_in),
2032 compiler.stack_assign(normal_out),
2033 compiler.stack_assign(dot_out));
2034 compiler.add_node(
2035 __float_as_int(direction.x), __float_as_int(direction.y), __float_as_int(direction.z));
2036}
2037
2038void NormalNode::compile(OSLCompiler &compiler)
2039{
2040 compiler.parameter(this, "direction");
2041 compiler.add(this, "node_normal");
2042}
2043
2044/* Mapping */
2045
2047{
2048 NodeType *type = NodeType::add("mapping", create, NodeType::SHADER);
2049
2050 static NodeEnum type_enum;
2051 type_enum.insert("point", NODE_MAPPING_TYPE_POINT);
2052 type_enum.insert("texture", NODE_MAPPING_TYPE_TEXTURE);
2053 type_enum.insert("vector", NODE_MAPPING_TYPE_VECTOR);
2054 type_enum.insert("normal", NODE_MAPPING_TYPE_NORMAL);
2055 SOCKET_ENUM(mapping_type, "Type", type_enum, NODE_MAPPING_TYPE_POINT);
2056
2057 SOCKET_IN_POINT(vector, "Vector", zero_float3());
2058 SOCKET_IN_POINT(location, "Location", zero_float3());
2059 SOCKET_IN_POINT(rotation, "Rotation", zero_float3());
2060 SOCKET_IN_POINT(scale, "Scale", one_float3());
2061
2062 SOCKET_OUT_POINT(vector, "Vector");
2063
2064 return type;
2065}
2066
2067MappingNode::MappingNode() : ShaderNode(get_node_type()) {}
2068
2070{
2071 if (folder.all_inputs_constant()) {
2072 float3 result = svm_mapping((NodeMappingType)mapping_type, vector, location, rotation, scale);
2073 folder.make_constant(result);
2074 }
2075 else {
2076 folder.fold_mapping((NodeMappingType)mapping_type);
2077 }
2078}
2079
2080void MappingNode::compile(SVMCompiler &compiler)
2081{
2082 ShaderInput *vector_in = input("Vector");
2083 ShaderInput *location_in = input("Location");
2084 ShaderInput *rotation_in = input("Rotation");
2085 ShaderInput *scale_in = input("Scale");
2086 ShaderOutput *vector_out = output("Vector");
2087
2088 int vector_stack_offset = compiler.stack_assign(vector_in);
2089 int location_stack_offset = compiler.stack_assign(location_in);
2090 int rotation_stack_offset = compiler.stack_assign(rotation_in);
2091 int scale_stack_offset = compiler.stack_assign(scale_in);
2092 int result_stack_offset = compiler.stack_assign(vector_out);
2093
2094 compiler.add_node(
2095 NODE_MAPPING,
2096 mapping_type,
2097 compiler.encode_uchar4(
2098 vector_stack_offset, location_stack_offset, rotation_stack_offset, scale_stack_offset),
2099 result_stack_offset);
2100}
2101
2102void MappingNode::compile(OSLCompiler &compiler)
2103{
2104 compiler.parameter(this, "mapping_type");
2105 compiler.add(this, "node_mapping");
2106}
2107
2108/* RGBToBW */
2109
2111{
2112 NodeType *type = NodeType::add("rgb_to_bw", create, NodeType::SHADER);
2113
2114 SOCKET_IN_COLOR(color, "Color", zero_float3());
2115 SOCKET_OUT_FLOAT(val, "Val");
2116
2117 return type;
2118}
2119
2120RGBToBWNode::RGBToBWNode() : ShaderNode(get_node_type()) {}
2121
2123{
2124 if (folder.all_inputs_constant()) {
2125 float val = folder.scene->shader_manager->linear_rgb_to_gray(color);
2126 folder.make_constant(val);
2127 }
2128}
2129
2130void RGBToBWNode::compile(SVMCompiler &compiler)
2131{
2132 compiler.add_node(NODE_CONVERT,
2134 compiler.stack_assign(inputs[0]),
2135 compiler.stack_assign(outputs[0]));
2136}
2137
2138void RGBToBWNode::compile(OSLCompiler &compiler)
2139{
2140 compiler.add(this, "node_rgb_to_bw");
2141}
2142
2143/* Convert */
2144
2145const NodeType *ConvertNode::node_types[ConvertNode::MAX_TYPE][ConvertNode::MAX_TYPE];
2146bool ConvertNode::initialized = ConvertNode::register_types();
2147
2148Node *ConvertNode::create(const NodeType *type)
2149{
2150 return new ConvertNode(type->inputs[0].type, type->outputs[0].type);
2151}
2152
2153bool ConvertNode::register_types()
2154{
2155 const int num_types = 8;
2156 SocketType::Type types[num_types] = {SocketType::FLOAT,
2164
2165 for (size_t i = 0; i < num_types; i++) {
2166 SocketType::Type from = types[i];
2167 ustring from_name(SocketType::type_name(from));
2168 ustring from_value_name("value_" + from_name.string());
2169
2170 for (size_t j = 0; j < num_types; j++) {
2171 SocketType::Type to = types[j];
2172 ustring to_name(SocketType::type_name(to));
2173 ustring to_value_name("value_" + to_name.string());
2174
2175 string node_name = "convert_" + from_name.string() + "_to_" + to_name.string();
2176 NodeType *type = NodeType::add(node_name.c_str(), create, NodeType::SHADER);
2177
2178 type->register_input(from_value_name,
2179 from_value_name,
2180 from,
2183 NULL,
2184 NULL,
2186 type->register_output(to_value_name, to_value_name, to);
2187
2188 assert(from < MAX_TYPE);
2189 assert(to < MAX_TYPE);
2190
2191 node_types[from][to] = type;
2192 }
2193 }
2194
2195 return true;
2196}
2197
2199 : ShaderNode(node_types[from_][to_])
2200{
2201 from = from_;
2202 to = to_;
2203
2204 if (from == to) {
2206 }
2207 else if (autoconvert) {
2209 }
2210}
2211
2212/* Union usage requires a manual copy constructor. */
2214 : ShaderNode(other),
2215 from(other.from),
2216 to(other.to),
2217 value_color(other.value_color),
2218 value_string(other.value_string)
2219{
2220}
2221
2223{
2224 /* proxy nodes should have been removed at this point */
2226
2227 if (folder.all_inputs_constant()) {
2228 if (from == SocketType::FLOAT || from == SocketType::INT) {
2229 float val = value_float;
2230 if (from == SocketType::INT) {
2231 val = value_int;
2232 }
2233 if (SocketType::is_float3(to)) {
2234 folder.make_constant(make_float3(val, val, val));
2235 }
2236 else if (to == SocketType::INT) {
2237 folder.make_constant((int)val);
2238 }
2239 else if (to == SocketType::FLOAT) {
2240 folder.make_constant(val);
2241 }
2242 }
2243 else if (SocketType::is_float3(from)) {
2244 if (to == SocketType::FLOAT || to == SocketType::INT) {
2245 float val;
2246 if (from == SocketType::COLOR) {
2247 /* color to scalar */
2249 }
2250 else {
2251 /* vector/point/normal to scalar */
2252 val = average(value_vector);
2253 }
2254 if (to == SocketType::INT) {
2255 folder.make_constant((int)val);
2256 }
2257 else if (to == SocketType::FLOAT) {
2258 folder.make_constant(val);
2259 }
2260 }
2261 else if (SocketType::is_float3(to)) {
2262 folder.make_constant(value_color);
2263 }
2264 }
2265 }
2266 else {
2267 ShaderInput *in = inputs[0];
2268 ShaderNode *prev = in->link->parent;
2269
2270 /* no-op conversion of A to B to A */
2271 if (prev->type == node_types[to][from]) {
2272 ShaderInput *prev_in = prev->inputs[0];
2273
2275 prev_in->link)
2276 {
2277 folder.bypass(prev_in->link);
2278 }
2279 }
2280 }
2281}
2282
2283void ConvertNode::compile(SVMCompiler &compiler)
2284{
2285 /* proxy nodes should have been removed at this point */
2287
2288 ShaderInput *in = inputs[0];
2289 ShaderOutput *out = outputs[0];
2290
2291 if (from == SocketType::FLOAT) {
2292 if (to == SocketType::INT) {
2293 /* float to int */
2294 compiler.add_node(
2295 NODE_CONVERT, NODE_CONVERT_FI, compiler.stack_assign(in), compiler.stack_assign(out));
2296 }
2297 else {
2298 /* float to float3 */
2299 compiler.add_node(
2300 NODE_CONVERT, NODE_CONVERT_FV, compiler.stack_assign(in), compiler.stack_assign(out));
2301 }
2302 }
2303 else if (from == SocketType::INT) {
2304 if (to == SocketType::FLOAT) {
2305 /* int to float */
2306 compiler.add_node(
2307 NODE_CONVERT, NODE_CONVERT_IF, compiler.stack_assign(in), compiler.stack_assign(out));
2308 }
2309 else {
2310 /* int to vector/point/normal */
2311 compiler.add_node(
2312 NODE_CONVERT, NODE_CONVERT_IV, compiler.stack_assign(in), compiler.stack_assign(out));
2313 }
2314 }
2315 else if (to == SocketType::FLOAT) {
2316 if (from == SocketType::COLOR) {
2317 /* color to float */
2318 compiler.add_node(
2319 NODE_CONVERT, NODE_CONVERT_CF, compiler.stack_assign(in), compiler.stack_assign(out));
2320 }
2321 else {
2322 /* vector/point/normal to float */
2323 compiler.add_node(
2324 NODE_CONVERT, NODE_CONVERT_VF, compiler.stack_assign(in), compiler.stack_assign(out));
2325 }
2326 }
2327 else if (to == SocketType::INT) {
2328 if (from == SocketType::COLOR) {
2329 /* color to int */
2330 compiler.add_node(
2331 NODE_CONVERT, NODE_CONVERT_CI, compiler.stack_assign(in), compiler.stack_assign(out));
2332 }
2333 else {
2334 /* vector/point/normal to int */
2335 compiler.add_node(
2336 NODE_CONVERT, NODE_CONVERT_VI, compiler.stack_assign(in), compiler.stack_assign(out));
2337 }
2338 }
2339 else {
2340 /* float3 to float3 */
2341 if (in->link) {
2342 /* no op in SVM */
2343 compiler.stack_link(in, out);
2344 }
2345 else {
2346 /* set 0,0,0 value */
2347 compiler.add_node(NODE_VALUE_V, compiler.stack_assign(out));
2348 compiler.add_node(NODE_VALUE_V, value_color);
2349 }
2350 }
2351}
2352
2353void ConvertNode::compile(OSLCompiler &compiler)
2354{
2355 /* proxy nodes should have been removed at this point */
2357
2358 if (from == SocketType::FLOAT) {
2359 compiler.add(this, "node_convert_from_float");
2360 }
2361 else if (from == SocketType::INT) {
2362 compiler.add(this, "node_convert_from_int");
2363 }
2364 else if (from == SocketType::COLOR) {
2365 compiler.add(this, "node_convert_from_color");
2366 }
2367 else if (from == SocketType::VECTOR) {
2368 compiler.add(this, "node_convert_from_vector");
2369 }
2370 else if (from == SocketType::POINT) {
2371 compiler.add(this, "node_convert_from_point");
2372 }
2373 else if (from == SocketType::NORMAL) {
2374 compiler.add(this, "node_convert_from_normal");
2375 }
2376 else {
2377 assert(0);
2378 }
2379}
2380
2381/* Base type for all closure-type nodes */
2382
2387
2389{
2390 /* detect if anything is plugged into the normal input besides the default */
2391 ShaderInput *normal_in = input("Normal");
2392 return (normal_in && normal_in->link &&
2394}
2395
2396/* BSDF Closure */
2397
2398BsdfNode::BsdfNode(const NodeType *node_type) : BsdfBaseNode(node_type) {}
2399
2401 ShaderInput *bsdf_y,
2402 ShaderInput *bsdf_z,
2403 ShaderInput *data_y,
2404 ShaderInput *data_z,
2405 ShaderInput *data_w)
2406{
2407 ShaderInput *color_in = input("Color");
2408 ShaderInput *normal_in = input("Normal");
2409
2410 if (color_in->link) {
2411 compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
2412 }
2413 else {
2414 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
2415 }
2416
2417 int normal_offset = (normal_in) ? compiler.stack_assign_if_linked(normal_in) : SVM_STACK_INVALID;
2418 int data_y_offset = (data_y) ? compiler.stack_assign(data_y) : SVM_STACK_INVALID;
2419 int data_z_offset = (data_z) ? compiler.stack_assign(data_z) : SVM_STACK_INVALID;
2420 int data_w_offset = (data_w) ? compiler.stack_assign(data_w) : SVM_STACK_INVALID;
2421
2422 compiler.add_node(
2423 NODE_CLOSURE_BSDF,
2424 compiler.encode_uchar4(closure,
2425 (bsdf_y) ? compiler.stack_assign(bsdf_y) : SVM_STACK_INVALID,
2426 (bsdf_z) ? compiler.stack_assign(bsdf_z) : SVM_STACK_INVALID,
2427 compiler.closure_mix_weight_offset()),
2428 __float_as_int((bsdf_y) ? get_float(bsdf_y->socket_type) : 0.0f),
2429 __float_as_int((bsdf_z) ? get_float(bsdf_z->socket_type) : 0.0f));
2430
2431 compiler.add_node(normal_offset, data_y_offset, data_z_offset, data_w_offset);
2432}
2433
2434void BsdfNode::compile(SVMCompiler &compiler)
2435{
2436 compile(compiler, NULL, NULL);
2437}
2438
2439void BsdfNode::compile(OSLCompiler & /*compiler*/)
2440{
2441 assert(0);
2442}
2443
2444/* Metallic BSDF Closure */
2445
2447{
2448 NodeType *type = NodeType::add("metallic_bsdf", create, NodeType::SHADER);
2449
2450 SOCKET_IN_COLOR(color, "Base Color", make_float3(0.617f, 0.577f, 0.540f));
2452 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2453
2454 static NodeEnum distribution_enum;
2455 distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
2456 distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_ID);
2457 distribution_enum.insert("multi_ggx", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
2459 distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
2460
2461 static NodeEnum fresnel_type_enum;
2462 fresnel_type_enum.insert("f82", CLOSURE_BSDF_F82_CONDUCTOR);
2463 fresnel_type_enum.insert("physical_conductor", CLOSURE_BSDF_PHYSICAL_CONDUCTOR);
2464 SOCKET_ENUM(fresnel_type, "fresnel_type", fresnel_type_enum, CLOSURE_BSDF_F82_CONDUCTOR);
2465
2466 SOCKET_IN_COLOR(edge_tint, "Edge Tint", make_float3(0.695f, 0.726f, 0.770f));
2467
2468 SOCKET_IN_VECTOR(ior, "IOR", make_float3(2.757f, 2.513f, 2.231f));
2469 SOCKET_IN_VECTOR(k, "Extinction", make_float3(3.867f, 3.404f, 3.009f));
2470
2472
2473 SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
2474 SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f);
2475 SOCKET_IN_FLOAT(rotation, "Rotation", 0.0f);
2476
2477 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2478
2479 return type;
2480}
2481
2482MetallicBsdfNode::MetallicBsdfNode() : BsdfNode(get_node_type())
2483{
2485}
2486
2488{
2489 ShaderInput *anisotropy_input = input("Anisotropy");
2490 /* Keep in sync with the thresholds in OSL's node_conductor_bsdf and SVM's
2491 * svm_node_metallic_bsdf. */
2492 return (!anisotropy_input->link && fabsf(anisotropy) <= 1e-4f);
2493}
2494
2496{
2497 if (shader->has_surface_link()) {
2498 ShaderInput *tangent_in = input("Tangent");
2499 if (!tangent_in->link && !is_isotropic()) {
2500 attributes->add(ATTR_STD_GENERATED);
2501 }
2502 }
2503
2504 ShaderNode::attributes(shader, attributes);
2505}
2506
2508{
2509 /* If the anisotropy is close enough to zero, fall back to the isotropic case. */
2510 ShaderInput *tangent_input = input("Tangent");
2511 if (tangent_input->link && is_isotropic()) {
2512 tangent_input->disconnect();
2513 }
2514}
2515
2517{
2518 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, one_float3());
2519
2520 ShaderInput *base_color_in = input("Base Color");
2521 ShaderInput *edge_tint_in = input("Edge Tint");
2522 ShaderInput *ior_in = input("IOR");
2523 ShaderInput *k_in = input("Extinction");
2524
2525 int base_color_ior_offset = fresnel_type == CLOSURE_BSDF_PHYSICAL_CONDUCTOR ?
2526 compiler.stack_assign(ior_in) :
2527 compiler.stack_assign(base_color_in);
2528 int edge_tint_k_offset = fresnel_type == CLOSURE_BSDF_PHYSICAL_CONDUCTOR ?
2529 compiler.stack_assign(k_in) :
2530 compiler.stack_assign(edge_tint_in);
2531
2532 ShaderInput *anisotropy_in = input("Anisotropy");
2533 ShaderInput *rotation_in = input("Rotation");
2534 ShaderInput *roughness_in = input("Roughness");
2535 ShaderInput *tangent_in = input("Tangent");
2536
2537 int normal_offset = compiler.stack_assign_if_linked(input("Normal"));
2538
2539 compiler.add_node(NODE_CLOSURE_BSDF,
2540 compiler.encode_uchar4(fresnel_type,
2541 compiler.stack_assign(roughness_in),
2542 compiler.stack_assign(anisotropy_in),
2543 compiler.closure_mix_weight_offset()),
2544 compiler.encode_uchar4(base_color_ior_offset,
2545 edge_tint_k_offset,
2546 compiler.stack_assign(rotation_in),
2547 compiler.stack_assign(tangent_in)),
2548 distribution);
2549 compiler.add_node(normal_offset);
2550}
2551
2553{
2554 compiler.parameter(this, "distribution");
2555 compiler.parameter(this, "fresnel_type");
2556 compiler.add(this, "node_metallic_bsdf");
2557}
2558
2559/* Glossy BSDF Closure */
2560
2562{
2563 NodeType *type = NodeType::add("glossy_bsdf", create, NodeType::SHADER);
2564
2565 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2567 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2568
2569 static NodeEnum distribution_enum;
2570 distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
2571 distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_ID);
2572 distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
2573 distribution_enum.insert("multi_ggx", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
2574 SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID);
2575
2577
2578 SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
2579 SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f);
2580 SOCKET_IN_FLOAT(rotation, "Rotation", 0.0f);
2581
2582 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2583
2584 return type;
2585}
2586
2587GlossyBsdfNode::GlossyBsdfNode() : BsdfNode(get_node_type())
2588{
2590}
2591
2593{
2594 ShaderInput *anisotropy_input = input("Anisotropy");
2595 /* Keep in sync with the thresholds in OSL's node_glossy_bsdf and SVM's svm_node_closure_bsdf. */
2596 return (!anisotropy_input->link && fabsf(anisotropy) <= 1e-4f);
2597}
2598
2600{
2601 if (shader->has_surface_link()) {
2602 ShaderInput *tangent_in = input("Tangent");
2603 if (!tangent_in->link && !is_isotropic()) {
2604 attributes->add(ATTR_STD_GENERATED);
2605 }
2606 }
2607
2608 ShaderNode::attributes(shader, attributes);
2609}
2610
2612{
2613 /* If the anisotropy is close enough to zero, fall back to the isotropic case. */
2614 ShaderInput *tangent_input = input("Tangent");
2615 if (tangent_input->link && is_isotropic()) {
2616 tangent_input->disconnect();
2617 }
2618}
2619
2621{
2622 closure = distribution;
2623
2624 ShaderInput *tangent = input("Tangent");
2625 tangent = compiler.is_linked(tangent) ? tangent : nullptr;
2626
2627 /* TODO: Just use weight for legacy MultiGGX? Would also simplify OSL. */
2629 BsdfNode::compile(compiler,
2630 input("Roughness"),
2631 input("Anisotropy"),
2632 input("Rotation"),
2633 input("Color"),
2634 tangent);
2635 }
2636 else {
2638 compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), nullptr, tangent);
2639 }
2640}
2641
2643{
2644 compiler.parameter(this, "distribution");
2645 compiler.add(this, "node_glossy_bsdf");
2646}
2647
2648/* Glass BSDF Closure */
2649
2651{
2652 NodeType *type = NodeType::add("glass_bsdf", create, NodeType::SHADER);
2653
2654 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2656 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2657
2658 static NodeEnum distribution_enum;
2659 distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID);
2660 distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
2661 distribution_enum.insert("multi_ggx", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
2663 distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
2664 SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
2665 SOCKET_IN_FLOAT(IOR, "IOR", 1.5f);
2666
2667 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2668
2669 return type;
2670}
2671
2672GlassBsdfNode::GlassBsdfNode() : BsdfNode(get_node_type())
2673{
2675}
2676
2677void GlassBsdfNode::compile(SVMCompiler &compiler)
2678{
2679 closure = distribution;
2680 BsdfNode::compile(compiler, input("Roughness"), input("IOR"), input("Color"));
2681}
2682
2683void GlassBsdfNode::compile(OSLCompiler &compiler)
2684{
2685 compiler.parameter(this, "distribution");
2686 compiler.add(this, "node_glass_bsdf");
2687}
2688
2689/* Refraction BSDF Closure */
2690
2692{
2693 NodeType *type = NodeType::add("refraction_bsdf", create, NodeType::SHADER);
2694
2695 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2697 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2698
2699 static NodeEnum distribution_enum;
2700 distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
2701 distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
2703 distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
2704
2705 SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
2706 SOCKET_IN_FLOAT(IOR, "IOR", 0.3f);
2707
2708 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2709
2710 return type;
2711}
2712
2713RefractionBsdfNode::RefractionBsdfNode() : BsdfNode(get_node_type())
2714{
2716}
2717
2719{
2720 closure = distribution;
2721
2722 BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
2723}
2724
2726{
2727 compiler.parameter(this, "distribution");
2728 compiler.add(this, "node_refraction_bsdf");
2729}
2730
2731/* Toon BSDF Closure */
2732
2734{
2735 NodeType *type = NodeType::add("toon_bsdf", create, NodeType::SHADER);
2736
2737 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2739 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2740
2741 static NodeEnum component_enum;
2742 component_enum.insert("diffuse", CLOSURE_BSDF_DIFFUSE_TOON_ID);
2743 component_enum.insert("glossy", CLOSURE_BSDF_GLOSSY_TOON_ID);
2744 SOCKET_ENUM(component, "Component", component_enum, CLOSURE_BSDF_DIFFUSE_TOON_ID);
2745 SOCKET_IN_FLOAT(size, "Size", 0.5f);
2746 SOCKET_IN_FLOAT(smooth, "Smooth", 0.0f);
2747
2748 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2749
2750 return type;
2751}
2752
2753ToonBsdfNode::ToonBsdfNode() : BsdfNode(get_node_type())
2754{
2756}
2757
2758void ToonBsdfNode::compile(SVMCompiler &compiler)
2759{
2760 closure = component;
2761
2762 BsdfNode::compile(compiler, input("Size"), input("Smooth"));
2763}
2764
2765void ToonBsdfNode::compile(OSLCompiler &compiler)
2766{
2767 compiler.parameter(this, "component");
2768 compiler.add(this, "node_toon_bsdf");
2769}
2770
2771/* Sheen BSDF Closure */
2772
2774{
2775 NodeType *type = NodeType::add("sheen_bsdf", create, NodeType::SHADER);
2776
2777 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2779 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2780 SOCKET_IN_FLOAT(roughness, "Roughness", 1.0f);
2781
2782 static NodeEnum distribution_enum;
2783 distribution_enum.insert("ashikhmin", CLOSURE_BSDF_ASHIKHMIN_VELVET_ID);
2784 distribution_enum.insert("microfiber", CLOSURE_BSDF_SHEEN_ID);
2785 SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_SHEEN_ID);
2786
2787 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2788
2789 return type;
2790}
2791
2792SheenBsdfNode::SheenBsdfNode() : BsdfNode(get_node_type())
2793{
2794 closure = CLOSURE_BSDF_SHEEN_ID;
2795}
2796
2797void SheenBsdfNode::compile(SVMCompiler &compiler)
2798{
2799 closure = distribution;
2800 BsdfNode::compile(compiler, input("Roughness"), NULL);
2801}
2802
2803void SheenBsdfNode::compile(OSLCompiler &compiler)
2804{
2805 compiler.parameter(this, "distribution");
2806 compiler.add(this, "node_sheen_bsdf");
2807}
2808
2809/* Diffuse BSDF Closure */
2810
2812{
2813 NodeType *type = NodeType::add("diffuse_bsdf", create, NodeType::SHADER);
2814
2815 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2817 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2818 SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
2819
2820 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2821
2822 return type;
2823}
2824
2825DiffuseBsdfNode::DiffuseBsdfNode() : BsdfNode(get_node_type())
2826{
2827 closure = CLOSURE_BSDF_DIFFUSE_ID;
2828}
2829
2831{
2832 BsdfNode::compile(compiler, input("Roughness"), nullptr, input("Color"));
2833}
2834
2836{
2837 compiler.add(this, "node_diffuse_bsdf");
2838}
2839
2840/* Disney principled BSDF Closure */
2842{
2843 NodeType *type = NodeType::add("principled_bsdf", create, NodeType::SHADER);
2844
2845 static NodeEnum distribution_enum;
2846 distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
2847 distribution_enum.insert("multi_ggx", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
2849 distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
2850
2851 static NodeEnum subsurface_method_enum;
2852 subsurface_method_enum.insert("burley", CLOSURE_BSSRDF_BURLEY_ID);
2853 subsurface_method_enum.insert("random_walk", CLOSURE_BSSRDF_RANDOM_WALK_ID);
2854 subsurface_method_enum.insert("random_walk_skin", CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID);
2855 SOCKET_ENUM(subsurface_method,
2856 "Subsurface Method",
2857 subsurface_method_enum,
2859
2860 SOCKET_IN_COLOR(base_color, "Base Color", make_float3(0.8f, 0.8f, 0.8f))
2861 SOCKET_IN_FLOAT(metallic, "Metallic", 0.0f);
2862 SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
2863 SOCKET_IN_FLOAT(ior, "IOR", 1.5f);
2864 SOCKET_IN_FLOAT(alpha, "Alpha", 1.0f);
2866
2867 SOCKET_IN_FLOAT(diffuse_roughness, "Diffuse Roughness", 0.0f);
2868
2869 SOCKET_IN_FLOAT(subsurface_weight, "Subsurface Weight", 0.0f);
2870 SOCKET_IN_FLOAT(subsurface_scale, "Subsurface Scale", 0.1f);
2871 SOCKET_IN_VECTOR(subsurface_radius, "Subsurface Radius", make_float3(0.1f, 0.1f, 0.1f));
2872 SOCKET_IN_FLOAT(subsurface_ior, "Subsurface IOR", 1.4f);
2873 SOCKET_IN_FLOAT(subsurface_anisotropy, "Subsurface Anisotropy", 0.0f);
2874
2875 SOCKET_IN_FLOAT(specular_ior_level, "Specular IOR Level", 0.0f);
2876 SOCKET_IN_COLOR(specular_tint, "Specular Tint", one_float3());
2877 SOCKET_IN_FLOAT(anisotropic, "Anisotropic", 0.0f);
2878 SOCKET_IN_FLOAT(anisotropic_rotation, "Anisotropic Rotation", 0.0f);
2880
2881 SOCKET_IN_FLOAT(transmission_weight, "Transmission Weight", 0.0f);
2882
2883 SOCKET_IN_FLOAT(sheen_weight, "Sheen Weight", 0.0f);
2884 SOCKET_IN_FLOAT(sheen_roughness, "Sheen Roughness", 0.5f);
2885 SOCKET_IN_COLOR(sheen_tint, "Sheen Tint", one_float3());
2886
2887 SOCKET_IN_FLOAT(coat_weight, "Coat Weight", 0.0f);
2888 SOCKET_IN_FLOAT(coat_roughness, "Coat Roughness", 0.03f);
2889 SOCKET_IN_FLOAT(coat_ior, "Coat IOR", 1.5f);
2890 SOCKET_IN_COLOR(coat_tint, "Coat Tint", one_float3());
2891 SOCKET_IN_NORMAL(coat_normal, "Coat Normal", zero_float3(), SocketType::LINK_NORMAL);
2892
2893 SOCKET_IN_COLOR(emission_color, "Emission Color", one_float3());
2894 SOCKET_IN_FLOAT(emission_strength, "Emission Strength", 0.0f);
2895
2896 SOCKET_IN_FLOAT(thin_film_thickness, "Thin Film Thickness", 0.0f);
2897 SOCKET_IN_FLOAT(thin_film_ior, "Thin Film IOR", 1.3f);
2898
2899 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2900
2901 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2902
2903 return type;
2904}
2905
2906PrincipledBsdfNode::PrincipledBsdfNode() : BsdfBaseNode(get_node_type())
2907{
2910}
2911
2913{
2914 if (!has_surface_emission()) {
2915 /* Emission will be zero, so optimize away any connected emission input. */
2916 ShaderInput *emission_in = input("Emission Color");
2917 ShaderInput *strength_in = input("Emission Strength");
2918 if (emission_in->link) {
2919 emission_in->disconnect();
2920 }
2921 if (strength_in->link) {
2922 strength_in->disconnect();
2923 }
2924 }
2925}
2926
2928{
2929 ShaderInput *alpha_in = input("Alpha");
2930 return (alpha_in->link != NULL || alpha < (1.0f - CLOSURE_WEIGHT_CUTOFF));
2931}
2932
2934{
2935 ShaderInput *emission_color_in = input("Emission Color");
2936 ShaderInput *emission_strength_in = input("Emission Strength");
2937 return (emission_color_in->link != NULL || reduce_max(emission_color) > CLOSURE_WEIGHT_CUTOFF) &&
2938 (emission_strength_in->link != NULL || emission_strength > CLOSURE_WEIGHT_CUTOFF);
2939}
2940
2942{
2943 ShaderInput *subsurface_weight_in = input("Subsurface Weight");
2944 ShaderInput *subsurface_scale_in = input("Subsurface Scale");
2945 return (subsurface_weight_in->link != NULL || subsurface_weight > CLOSURE_WEIGHT_CUTOFF) &&
2946 (subsurface_scale_in->link != NULL || subsurface_scale != 0.0f);
2947}
2948
2950{
2951 if (shader->has_surface_link()) {
2952 ShaderInput *tangent_in = input("Tangent");
2953
2954 if (!tangent_in->link) {
2955 attributes->add(ATTR_STD_GENERATED);
2956 }
2957 }
2958
2959 ShaderNode::attributes(shader, attributes);
2960}
2961
2963{
2964 ShaderInput *base_color_in = input("Base Color");
2965
2966 ShaderInput *p_metallic = input("Metallic");
2967 ShaderInput *p_subsurface_weight = input("Subsurface Weight");
2968
2969 ShaderInput *emission_strength_in = input("Emission Strength");
2970 ShaderInput *alpha_in = input("Alpha");
2971
2972 float3 weight = one_float3();
2973
2974 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, weight);
2975
2976 int normal_offset = compiler.stack_assign_if_linked(input("Normal"));
2977 int coat_normal_offset = compiler.stack_assign_if_linked(input("Coat Normal"));
2978 int tangent_offset = compiler.stack_assign_if_linked(input("Tangent"));
2979 int specular_ior_level_offset = compiler.stack_assign(input("Specular IOR Level"));
2980 int roughness_offset = compiler.stack_assign(input("Roughness"));
2981 int diffuse_roughness_offset = compiler.stack_assign(input("Diffuse Roughness"));
2982 int specular_tint_offset = compiler.stack_assign(input("Specular Tint"));
2983 int anisotropic_offset = compiler.stack_assign(input("Anisotropic"));
2984 int sheen_weight_offset = compiler.stack_assign(input("Sheen Weight"));
2985 int sheen_roughness_offset = compiler.stack_assign(input("Sheen Roughness"));
2986 int sheen_tint_offset = compiler.stack_assign(input("Sheen Tint"));
2987 int coat_weight_offset = compiler.stack_assign(input("Coat Weight"));
2988 int coat_roughness_offset = compiler.stack_assign(input("Coat Roughness"));
2989 int coat_ior_offset = compiler.stack_assign(input("Coat IOR"));
2990 int coat_tint_offset = compiler.stack_assign(input("Coat Tint"));
2991 int ior_offset = compiler.stack_assign(input("IOR"));
2992 int transmission_weight_offset = compiler.stack_assign(input("Transmission Weight"));
2993 int anisotropic_rotation_offset = compiler.stack_assign(input("Anisotropic Rotation"));
2994 int subsurface_radius_offset = compiler.stack_assign(input("Subsurface Radius"));
2995 int subsurface_scale_offset = compiler.stack_assign(input("Subsurface Scale"));
2996 int subsurface_ior_offset = compiler.stack_assign(input("Subsurface IOR"));
2997 int subsurface_anisotropy_offset = compiler.stack_assign(input("Subsurface Anisotropy"));
2998 int alpha_offset = compiler.stack_assign_if_linked(alpha_in);
2999 int emission_strength_offset = compiler.stack_assign_if_linked(emission_strength_in);
3000 int emission_color_offset = compiler.stack_assign(input("Emission Color"));
3001 int thin_film_thickness_offset = compiler.stack_assign(input("Thin Film Thickness"));
3002 int thin_film_ior_offset = compiler.stack_assign(input("Thin Film IOR"));
3003
3004 compiler.add_node(
3005 NODE_CLOSURE_BSDF,
3006 compiler.encode_uchar4(closure,
3007 compiler.stack_assign(p_metallic),
3008 compiler.stack_assign(p_subsurface_weight),
3009 compiler.closure_mix_weight_offset()),
3010 __float_as_int((p_metallic) ? get_float(p_metallic->socket_type) : 0.0f),
3011 __float_as_int((p_subsurface_weight) ? get_float(p_subsurface_weight->socket_type) : 0.0f));
3012
3013 compiler.add_node(
3014 normal_offset,
3015 tangent_offset,
3016 compiler.encode_uchar4(
3017 specular_ior_level_offset, roughness_offset, specular_tint_offset, anisotropic_offset),
3018 compiler.encode_uchar4(sheen_weight_offset,
3019 sheen_tint_offset,
3020 sheen_roughness_offset,
3021 diffuse_roughness_offset));
3022
3023 compiler.add_node(
3024 compiler.encode_uchar4(
3025 ior_offset, transmission_weight_offset, anisotropic_rotation_offset, coat_normal_offset),
3026 distribution,
3027 subsurface_method,
3028 compiler.encode_uchar4(
3029 coat_weight_offset, coat_roughness_offset, coat_ior_offset, coat_tint_offset));
3030
3031 float3 bc_default = get_float3(base_color_in->socket_type);
3032
3033 compiler.add_node(
3034 ((base_color_in->link) ? compiler.stack_assign(base_color_in) : SVM_STACK_INVALID),
3035 __float_as_int(bc_default.x),
3036 __float_as_int(bc_default.y),
3037 __float_as_int(bc_default.z));
3038
3039 compiler.add_node(subsurface_ior_offset,
3040 subsurface_radius_offset,
3041 subsurface_scale_offset,
3042 subsurface_anisotropy_offset);
3043
3044 compiler.add_node(compiler.encode_uchar4(alpha_offset,
3045 emission_strength_offset,
3046 emission_color_offset,
3047 thin_film_thickness_offset),
3049 __float_as_int(get_float(emission_strength_in->socket_type)),
3050 thin_film_ior_offset);
3051}
3052
3054{
3055 compiler.parameter(this, "distribution");
3056 compiler.parameter(this, "subsurface_method");
3057 compiler.add(this, "node_principled_bsdf");
3058}
3059
3064
3065/* Translucent BSDF Closure */
3066
3068{
3069 NodeType *type = NodeType::add("translucent_bsdf", create, NodeType::SHADER);
3070
3071 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3073 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3074
3075 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
3076
3077 return type;
3078}
3079
3080TranslucentBsdfNode::TranslucentBsdfNode() : BsdfNode(get_node_type())
3081{
3083}
3084
3086{
3087 BsdfNode::compile(compiler, NULL, NULL);
3088}
3089
3091{
3092 compiler.add(this, "node_translucent_bsdf");
3093}
3094
3095/* Transparent BSDF Closure */
3096
3098{
3099 NodeType *type = NodeType::add("transparent_bsdf", create, NodeType::SHADER);
3100
3101 SOCKET_IN_COLOR(color, "Color", one_float3());
3102 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3103
3104 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
3105
3106 return type;
3107}
3108
3109TransparentBsdfNode::TransparentBsdfNode() : BsdfNode(get_node_type())
3110{
3112}
3113
3115{
3116 BsdfNode::compile(compiler, NULL, NULL);
3117}
3118
3120{
3121 compiler.add(this, "node_transparent_bsdf");
3122}
3123
3124/* Ray Portal BSDF Closure */
3125
3127{
3128 NodeType *type = NodeType::add("ray_portal_bsdf", create, NodeType::SHADER);
3129
3130 SOCKET_IN_COLOR(color, "Color", one_float3());
3131 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3132
3133 SOCKET_IN_VECTOR(position, "Position", zero_float3(), SocketType::LINK_POSITION);
3134 SOCKET_IN_VECTOR(direction, "Direction", zero_float3());
3135
3136 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
3137
3138 return type;
3139}
3140
3141RayPortalBsdfNode::RayPortalBsdfNode() : BsdfNode(get_node_type())
3142{
3144}
3145
3147{
3148 BsdfNode::compile(compiler, NULL, NULL, input("Position"), input("Direction"));
3149}
3150
3152{
3153 compiler.add(this, "node_ray_portal_bsdf");
3154}
3155
3156/* Subsurface Scattering Closure */
3157
3159{
3160 NodeType *type = NodeType::add("subsurface_scattering", create, NodeType::SHADER);
3161
3162 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3164 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3165
3166 static NodeEnum method_enum;
3167 method_enum.insert("burley", CLOSURE_BSSRDF_BURLEY_ID);
3168 method_enum.insert("random_walk", CLOSURE_BSSRDF_RANDOM_WALK_ID);
3169 method_enum.insert("random_walk_skin", CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID);
3170 SOCKET_ENUM(method, "Method", method_enum, CLOSURE_BSSRDF_RANDOM_WALK_ID);
3171
3172 SOCKET_IN_FLOAT(scale, "Scale", 0.01f);
3173 SOCKET_IN_VECTOR(radius, "Radius", make_float3(0.1f, 0.1f, 0.1f));
3174
3175 SOCKET_IN_FLOAT(subsurface_ior, "IOR", 1.4f);
3176 SOCKET_IN_FLOAT(subsurface_roughness, "Roughness", 1.0f);
3177 SOCKET_IN_FLOAT(subsurface_anisotropy, "Anisotropy", 0.0f);
3178
3179 SOCKET_OUT_CLOSURE(BSSRDF, "BSSRDF");
3180
3181 return type;
3182}
3183
3184SubsurfaceScatteringNode::SubsurfaceScatteringNode() : BsdfNode(get_node_type())
3185{
3186 closure = method;
3187}
3188
3190{
3191 closure = method;
3192 BsdfNode::compile(compiler,
3193 input("Scale"),
3194 input("IOR"),
3195 input("Radius"),
3196 input("Anisotropy"),
3197 input("Roughness"));
3198}
3199
3201{
3202 closure = method;
3203 compiler.parameter(this, "method");
3204 compiler.add(this, "node_subsurface_scattering");
3205}
3206
3208{
3209 /* detect if anything is plugged into the normal input besides the default */
3210 ShaderInput *normal_in = input("Normal");
3211 return (normal_in->link &&
3213}
3214
3215/* Emissive Closure */
3216
3218{
3219 NodeType *type = NodeType::add("emission", create, NodeType::SHADER);
3220
3221 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3222 SOCKET_IN_FLOAT(strength, "Strength", 10.0f);
3223 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3224
3225 SOCKET_OUT_CLOSURE(emission, "Emission");
3226
3227 return type;
3228}
3229
3230EmissionNode::EmissionNode() : ShaderNode(get_node_type()) {}
3231
3232void EmissionNode::compile(SVMCompiler &compiler)
3233{
3234 ShaderInput *color_in = input("Color");
3235 ShaderInput *strength_in = input("Strength");
3236
3237 if (color_in->link || strength_in->link) {
3238 compiler.add_node(
3239 NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
3240 }
3241 else {
3242 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
3243 }
3244
3245 compiler.add_node(NODE_CLOSURE_EMISSION, compiler.closure_mix_weight_offset());
3246}
3247
3248void EmissionNode::compile(OSLCompiler &compiler)
3249{
3250 compiler.add(this, "node_emission");
3251}
3252
3254{
3255 ShaderInput *color_in = input("Color");
3256 ShaderInput *strength_in = input("Strength");
3257
3258 if ((!color_in->link && color == zero_float3()) || (!strength_in->link && strength == 0.0f)) {
3259 folder.discard();
3260 }
3261}
3262
3263/* Background Closure */
3264
3266{
3267 NodeType *type = NodeType::add("background_shader", create, NodeType::SHADER);
3268
3269 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3270 SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
3271 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3272
3273 SOCKET_OUT_CLOSURE(background, "Background");
3274
3275 return type;
3276}
3277
3278BackgroundNode::BackgroundNode() : ShaderNode(get_node_type()) {}
3279
3281{
3282 ShaderInput *color_in = input("Color");
3283 ShaderInput *strength_in = input("Strength");
3284
3285 if (color_in->link || strength_in->link) {
3286 compiler.add_node(
3287 NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
3288 }
3289 else {
3290 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
3291 }
3292
3293 compiler.add_node(NODE_CLOSURE_BACKGROUND, compiler.closure_mix_weight_offset());
3294}
3295
3297{
3298 compiler.add(this, "node_background");
3299}
3300
3302{
3303 ShaderInput *color_in = input("Color");
3304 ShaderInput *strength_in = input("Strength");
3305
3306 if ((!color_in->link && color == zero_float3()) || (!strength_in->link && strength == 0.0f)) {
3307 folder.discard();
3308 }
3309}
3310
3311/* Holdout Closure */
3312
3314{
3315 NodeType *type = NodeType::add("holdout", create, NodeType::SHADER);
3316
3317 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3318 SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3319
3320 SOCKET_OUT_CLOSURE(holdout, "Holdout");
3321
3322 return type;
3323}
3324
3325HoldoutNode::HoldoutNode() : ShaderNode(get_node_type()) {}
3326
3327void HoldoutNode::compile(SVMCompiler &compiler)
3328{
3329 float3 value = one_float3();
3330
3331 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, value);
3332 compiler.add_node(NODE_CLOSURE_HOLDOUT, compiler.closure_mix_weight_offset());
3333}
3334
3335void HoldoutNode::compile(OSLCompiler &compiler)
3336{
3337 compiler.add(this, "node_holdout");
3338}
3339
3340/* Ambient Occlusion */
3341
3343{
3344 NodeType *type = NodeType::add("ambient_occlusion", create, NodeType::SHADER);
3345
3346 SOCKET_INT(samples, "Samples", 16);
3347
3348 SOCKET_IN_COLOR(color, "Color", one_float3());
3349 SOCKET_IN_FLOAT(distance, "Distance", 1.0f);
3351
3352 SOCKET_BOOLEAN(inside, "Inside", false);
3353 SOCKET_BOOLEAN(only_local, "Only Local", false);
3354
3355 SOCKET_OUT_COLOR(color, "Color");
3356 SOCKET_OUT_FLOAT(ao, "AO");
3357
3358 return type;
3359}
3360
3361AmbientOcclusionNode::AmbientOcclusionNode() : ShaderNode(get_node_type()) {}
3362
3364{
3365 ShaderInput *color_in = input("Color");
3366 ShaderInput *distance_in = input("Distance");
3367 ShaderInput *normal_in = input("Normal");
3368 ShaderOutput *color_out = output("Color");
3369 ShaderOutput *ao_out = output("AO");
3370
3371 int flags = (inside ? NODE_AO_INSIDE : 0) | (only_local ? NODE_AO_ONLY_LOCAL : 0);
3372
3373 if (!distance_in->link && distance == 0.0f) {
3374 flags |= NODE_AO_GLOBAL_RADIUS;
3375 }
3376
3377 compiler.add_node(NODE_AMBIENT_OCCLUSION,
3378 compiler.encode_uchar4(flags,
3379 compiler.stack_assign_if_linked(distance_in),
3380 compiler.stack_assign_if_linked(normal_in),
3381 compiler.stack_assign(ao_out)),
3382 compiler.encode_uchar4(compiler.stack_assign(color_in),
3383 compiler.stack_assign(color_out),
3384 samples),
3385 __float_as_uint(distance));
3386}
3387
3389{
3390 compiler.parameter(this, "samples");
3391 compiler.parameter(this, "inside");
3392 compiler.parameter(this, "only_local");
3393 compiler.add(this, "node_ambient_occlusion");
3394}
3395
3396/* Volume Closure */
3397
3402
3404 ShaderInput *density,
3405 ShaderInput *param1,
3406 ShaderInput *param2)
3407{
3408 ShaderInput *color_in = input("Color");
3409
3410 if (color_in->link) {
3411 compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
3412 }
3413 else {
3414 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
3415 }
3416
3417 /* Density and mix weight need to be stored the same way for all volume closures since there's
3418 * a shortcut code path if we only need the extinction value. */
3419 uint density_ofs = (density) ? compiler.stack_assign_if_linked(density) : SVM_STACK_INVALID;
3420 uint mix_weight_ofs = compiler.closure_mix_weight_offset();
3421
3422 if (param2 == nullptr) {
3423 /* More efficient packing if we don't need the second parameter. */
3424 uint param1_ofs = (param1) ? compiler.stack_assign_if_linked(param1) : SVM_STACK_INVALID;
3425 compiler.add_node(NODE_CLOSURE_VOLUME,
3426 compiler.encode_uchar4(closure, density_ofs, param1_ofs, mix_weight_ofs),
3427 __float_as_int((density) ? get_float(density->socket_type) : 0.0f),
3428 __float_as_int((param1) ? get_float(param1->socket_type) : 0.0f));
3429 }
3430 else {
3431 uint param1_ofs = (param1) ? compiler.stack_assign(param1) : SVM_STACK_INVALID;
3432 uint param2_ofs = (param2) ? compiler.stack_assign(param2) : SVM_STACK_INVALID;
3433 compiler.add_node(NODE_CLOSURE_VOLUME,
3434 compiler.encode_uchar4(closure, density_ofs, param1_ofs, mix_weight_ofs),
3435 __float_as_int((density) ? get_float(density->socket_type) : 0.0f),
3436 param2_ofs);
3437 }
3438}
3439
3440void VolumeNode::compile(SVMCompiler &compiler)
3441{
3442 compile(compiler, nullptr, nullptr, nullptr);
3443}
3444
3445void VolumeNode::compile(OSLCompiler & /*compiler*/)
3446{
3447 assert(0);
3448}
3449
3450/* Absorption Volume Closure */
3451
3453{
3454 NodeType *type = NodeType::add("absorption_volume", create, NodeType::SHADER);
3455
3456 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3457 SOCKET_IN_FLOAT(density, "Density", 1.0f);
3458 SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3459
3460 SOCKET_OUT_CLOSURE(volume, "Volume");
3461
3462 return type;
3463}
3464
3465AbsorptionVolumeNode::AbsorptionVolumeNode() : VolumeNode(get_node_type())
3466{
3468}
3469
3471{
3472 VolumeNode::compile(compiler, input("Density"));
3473}
3474
3476{
3477 compiler.add(this, "node_absorption_volume");
3478}
3479
3480/* Scatter Volume Closure */
3481
3483{
3484 NodeType *type = NodeType::add("scatter_volume", create, NodeType::SHADER);
3485
3486 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3487 SOCKET_IN_FLOAT(density, "Density", 1.0f);
3488 SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f);
3489 SOCKET_IN_FLOAT(IOR, "IOR", 1.33f);
3490 SOCKET_IN_FLOAT(backscatter, "Backscatter", 0.1f);
3491 SOCKET_IN_FLOAT(alpha, "Alpha", 0.5f);
3492 SOCKET_IN_FLOAT(diameter, "Diameter", 20.0f);
3493
3494 static NodeEnum phase_enum;
3495 phase_enum.insert("Henyey-Greenstein", CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID);
3496 phase_enum.insert("Fournier-Forand", CLOSURE_VOLUME_FOURNIER_FORAND_ID);
3497 phase_enum.insert("Draine", CLOSURE_VOLUME_DRAINE_ID);
3498 phase_enum.insert("Rayleigh", CLOSURE_VOLUME_RAYLEIGH_ID);
3499 phase_enum.insert("Mie", CLOSURE_VOLUME_MIE_ID);
3500 SOCKET_ENUM(phase, "Phase", phase_enum, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID);
3501
3502 SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3503
3504 SOCKET_OUT_CLOSURE(volume, "Volume");
3505
3506 return type;
3507}
3508
3509ScatterVolumeNode::ScatterVolumeNode() : VolumeNode(get_node_type())
3510{
3512}
3513
3515{
3516 closure = phase;
3517
3518 switch (phase) {
3520 VolumeNode::compile(compiler, input("Density"), input("Anisotropy"));
3521 break;
3523 VolumeNode::compile(compiler, input("Density"), input("IOR"), input("Backscatter"));
3524 break;
3526 VolumeNode::compile(compiler, input("Density"));
3527 break;
3529 VolumeNode::compile(compiler, input("Density"), input("Anisotropy"), input("Alpha"));
3530 break;
3532 VolumeNode::compile(compiler, input("Density"), input("Diameter"));
3533 break;
3534 default:
3535 assert(false);
3536 break;
3537 }
3538}
3539
3541{
3542 compiler.parameter(this, "phase");
3543 compiler.add(this, "node_scatter_volume");
3544}
3545
3546/* Principled Volume Closure */
3547
3549{
3550 NodeType *type = NodeType::add("principled_volume", create, NodeType::SHADER);
3551
3552 SOCKET_IN_STRING(density_attribute, "Density Attribute", ustring());
3553 SOCKET_IN_STRING(color_attribute, "Color Attribute", ustring());
3554 SOCKET_IN_STRING(temperature_attribute, "Temperature Attribute", ustring());
3555
3556 SOCKET_IN_COLOR(color, "Color", make_float3(0.5f, 0.5f, 0.5f));
3557 SOCKET_IN_FLOAT(density, "Density", 1.0f);
3558 SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f);
3559 SOCKET_IN_COLOR(absorption_color, "Absorption Color", zero_float3());
3560 SOCKET_IN_FLOAT(emission_strength, "Emission Strength", 0.0f);
3561 SOCKET_IN_COLOR(emission_color, "Emission Color", one_float3());
3562 SOCKET_IN_FLOAT(blackbody_intensity, "Blackbody Intensity", 0.0f);
3563 SOCKET_IN_COLOR(blackbody_tint, "Blackbody Tint", one_float3());
3564 SOCKET_IN_FLOAT(temperature, "Temperature", 1000.0f);
3565 SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3566
3567 SOCKET_OUT_CLOSURE(volume, "Volume");
3568
3569 return type;
3570}
3571
3572PrincipledVolumeNode::PrincipledVolumeNode() : VolumeNode(get_node_type())
3573{
3575 density_attribute = ustring("density");
3576 temperature_attribute = ustring("temperature");
3577}
3578
3580{
3581 if (shader->has_volume) {
3582 ShaderInput *density_in = input("Density");
3583 ShaderInput *blackbody_in = input("Blackbody Intensity");
3584
3585 if (density_in->link || density > 0.0f) {
3586 attributes->add_standard(density_attribute);
3587 attributes->add_standard(color_attribute);
3588 }
3589
3590 if (blackbody_in->link || blackbody_intensity > 0.0f) {
3591 attributes->add_standard(temperature_attribute);
3592 }
3593
3594 attributes->add(ATTR_STD_GENERATED_TRANSFORM);
3595 }
3596
3597 ShaderNode::attributes(shader, attributes);
3598}
3599
3601{
3602 ShaderInput *color_in = input("Color");
3603 ShaderInput *density_in = input("Density");
3604 ShaderInput *anisotropy_in = input("Anisotropy");
3605 ShaderInput *absorption_color_in = input("Absorption Color");
3606 ShaderInput *emission_in = input("Emission Strength");
3607 ShaderInput *emission_color_in = input("Emission Color");
3608 ShaderInput *blackbody_in = input("Blackbody Intensity");
3609 ShaderInput *blackbody_tint_in = input("Blackbody Tint");
3610 ShaderInput *temperature_in = input("Temperature");
3611
3612 if (color_in->link) {
3613 compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
3614 }
3615 else {
3616 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
3617 }
3618
3619 compiler.add_node(NODE_PRINCIPLED_VOLUME,
3620 compiler.encode_uchar4(compiler.stack_assign_if_linked(density_in),
3621 compiler.stack_assign_if_linked(anisotropy_in),
3622 compiler.stack_assign(absorption_color_in),
3623 compiler.closure_mix_weight_offset()),
3624 compiler.encode_uchar4(compiler.stack_assign_if_linked(emission_in),
3625 compiler.stack_assign(emission_color_in),
3626 compiler.stack_assign_if_linked(blackbody_in),
3627 compiler.stack_assign(temperature_in)),
3628 compiler.stack_assign(blackbody_tint_in));
3629
3630 int attr_density = compiler.attribute_standard(density_attribute);
3631 int attr_color = compiler.attribute_standard(color_attribute);
3632 int attr_temperature = compiler.attribute_standard(temperature_attribute);
3633
3634 compiler.add_node(__float_as_int(density),
3635 __float_as_int(anisotropy),
3636 __float_as_int(emission_strength),
3637 __float_as_int(blackbody_intensity));
3638
3639 compiler.add_node(attr_density, attr_color, attr_temperature);
3640}
3641
3643{
3644 if (Attribute::name_standard(density_attribute.c_str())) {
3645 density_attribute = ustring("geom:" + density_attribute.string());
3646 }
3647 if (Attribute::name_standard(color_attribute.c_str())) {
3648 color_attribute = ustring("geom:" + color_attribute.string());
3649 }
3650 if (Attribute::name_standard(temperature_attribute.c_str())) {
3651 temperature_attribute = ustring("geom:" + temperature_attribute.string());
3652 }
3653
3654 compiler.add(this, "node_principled_volume");
3655}
3656
3657/* Principled Hair BSDF Closure */
3658
3660{
3661 NodeType *type = NodeType::add("principled_hair_bsdf", create, NodeType::SHADER);
3662
3663 /* Scattering models. */
3664 static NodeEnum model_enum;
3665 model_enum.insert("Chiang", NODE_PRINCIPLED_HAIR_CHIANG);
3666 model_enum.insert("Huang", NODE_PRINCIPLED_HAIR_HUANG);
3667 SOCKET_ENUM(model, "Model", model_enum, NODE_PRINCIPLED_HAIR_HUANG);
3668
3669 /* Color parametrization specified as enum. */
3670 static NodeEnum parametrization_enum;
3671 parametrization_enum.insert("Direct coloring", NODE_PRINCIPLED_HAIR_REFLECTANCE);
3672 parametrization_enum.insert("Melanin concentration", NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION);
3673 parametrization_enum.insert("Absorption coefficient", NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION);
3675 parametrization, "Parametrization", parametrization_enum, NODE_PRINCIPLED_HAIR_REFLECTANCE);
3676
3677 /* Initialize sockets to their default values. */
3678 SOCKET_IN_COLOR(color, "Color", make_float3(0.017513f, 0.005763f, 0.002059f));
3679 SOCKET_IN_FLOAT(melanin, "Melanin", 0.8f);
3680 SOCKET_IN_FLOAT(melanin_redness, "Melanin Redness", 1.0f);
3681 SOCKET_IN_COLOR(tint, "Tint", make_float3(1.f, 1.f, 1.f));
3683 absorption_coefficient, "Absorption Coefficient", make_float3(0.245531f, 0.52f, 1.365f));
3684
3685 SOCKET_IN_FLOAT(aspect_ratio, "Aspect Ratio", 0.85f);
3686
3687 SOCKET_IN_FLOAT(offset, "Offset", 2.f * M_PI_F / 180.f);
3688 SOCKET_IN_FLOAT(roughness, "Roughness", 0.3f);
3689 SOCKET_IN_FLOAT(radial_roughness, "Radial Roughness", 0.3f);
3690 SOCKET_IN_FLOAT(coat, "Coat", 0.0f);
3691 SOCKET_IN_FLOAT(ior, "IOR", 1.55f);
3692
3693 SOCKET_IN_FLOAT(random_roughness, "Random Roughness", 0.0f);
3694 SOCKET_IN_FLOAT(random_color, "Random Color", 0.0f);
3695 SOCKET_IN_FLOAT(random, "Random", 0.0f);
3696
3697 SOCKET_IN_FLOAT(R, "R lobe", 1.0f);
3698 SOCKET_IN_FLOAT(TT, "TT lobe", 1.0f);
3699 SOCKET_IN_FLOAT(TRT, "TRT lobe", 1.0f);
3700
3701 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3702
3703 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
3704
3705 return type;
3706}
3707
3708PrincipledHairBsdfNode::PrincipledHairBsdfNode() : BsdfBaseNode(get_node_type())
3709{
3711}
3712
3713/* Treat hair as transparent if the hit is outside of the projected width. */
3715{
3716 if (model == NODE_PRINCIPLED_HAIR_HUANG) {
3717 if (aspect_ratio != 1.0f || input("Aspect Ratio")->link) {
3718 return true;
3719 }
3720 }
3721 return false;
3722}
3723
3725{
3727 /* Make sure we have the normal for elliptical cross section tracking. */
3728 attributes->add(ATTR_STD_VERTEX_NORMAL);
3729 }
3730
3731 if (!input("Random")->link) {
3732 /* Enable retrieving Hair Info -> Random if Random isn't linked. */
3733 attributes->add(ATTR_STD_CURVE_RANDOM);
3734 }
3735 ShaderNode::attributes(shader, attributes);
3736}
3737
3738/* Prepares the input data for the SVM shader. */
3740{
3743
3744 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, one_float3());
3745
3746 ShaderInput *roughness_in = input("Roughness");
3747 ShaderInput *radial_roughness_in = input("Radial Roughness");
3748 ShaderInput *random_roughness_in = input("Random Roughness");
3749 ShaderInput *offset_in = input("Offset");
3750 ShaderInput *coat_in = input("Coat");
3751 ShaderInput *ior_in = input("IOR");
3752
3753 ShaderInput *melanin_in = input("Melanin");
3754 ShaderInput *melanin_redness_in = input("Melanin Redness");
3755 ShaderInput *random_color_in = input("Random Color");
3756
3757 ShaderInput *R_in = input("R lobe");
3758 ShaderInput *TT_in = input("TT lobe");
3759 ShaderInput *TRT_in = input("TRT lobe");
3760
3761 ShaderInput *aspect_ratio_in = input("Aspect Ratio");
3762
3763 int color_ofs = compiler.stack_assign(input("Color"));
3764 int tint_ofs = compiler.stack_assign(input("Tint"));
3765 int absorption_coefficient_ofs = compiler.stack_assign(input("Absorption Coefficient"));
3766
3767 int roughness_ofs = compiler.stack_assign_if_linked(roughness_in);
3768 int radial_roughness_ofs = compiler.stack_assign_if_linked(radial_roughness_in);
3769
3770 int offset_ofs = compiler.stack_assign_if_linked(offset_in);
3771 int ior_ofs = compiler.stack_assign_if_linked(ior_in);
3772
3773 int coat_ofs = compiler.stack_assign_if_linked(coat_in);
3774 int melanin_ofs = compiler.stack_assign_if_linked(melanin_in);
3775 int melanin_redness_ofs = compiler.stack_assign_if_linked(melanin_redness_in);
3776
3777 ShaderInput *random_in = input("Random");
3778 int attr_random = random_in->link ? SVM_STACK_INVALID :
3780 int random_in_ofs = compiler.stack_assign_if_linked(random_in);
3781 int random_color_ofs = compiler.stack_assign_if_linked(random_color_in);
3782 int random_roughness_ofs = compiler.stack_assign_if_linked(random_roughness_in);
3783
3784 /* Encode all parameters into data nodes. */
3785 /* node */
3786 compiler.add_node(
3787 NODE_CLOSURE_BSDF,
3788 /* Socket IDs can be packed 4 at a time into a single data packet */
3789 compiler.encode_uchar4(
3790 closure, roughness_ofs, random_roughness_ofs, compiler.closure_mix_weight_offset()),
3791 /* The rest are stored as unsigned integers */
3792 __float_as_uint(roughness),
3793 __float_as_uint(random_roughness));
3794
3795 /* data node */
3796 compiler.add_node(SVM_STACK_INVALID,
3797 compiler.encode_uchar4(offset_ofs, ior_ofs, color_ofs, parametrization),
3798 __float_as_uint(offset),
3799 __float_as_uint(ior));
3800
3801 /* data node 2 */
3802 compiler.add_node(compiler.encode_uchar4(
3803 tint_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs),
3804 attr_random,
3805 __float_as_uint(melanin),
3806 __float_as_uint(melanin_redness));
3807
3808 /* data node 3 */
3809 if (model == NODE_PRINCIPLED_HAIR_HUANG) {
3810 compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(aspect_ratio_in),
3811 random_in_ofs,
3812 random_color_ofs,
3814 __float_as_uint(random),
3815 __float_as_uint(random_color),
3816 __float_as_uint(aspect_ratio));
3817 }
3818 else {
3819 compiler.add_node(
3820 compiler.encode_uchar4(coat_ofs, random_in_ofs, random_color_ofs, radial_roughness_ofs),
3821 __float_as_uint(random),
3822 __float_as_uint(random_color),
3823 __float_as_uint(coat));
3824 }
3825
3826 /* data node 4 */
3827 compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(R_in),
3828 compiler.stack_assign_if_linked(TT_in),
3829 compiler.stack_assign_if_linked(TRT_in),
3831 __float_as_uint(model == NODE_PRINCIPLED_HAIR_HUANG ? R : radial_roughness),
3832 __float_as_uint(TT),
3833 __float_as_uint(TRT));
3834}
3835
3836/* Prepares the input data for the OSL shader. */
3838{
3839 compiler.parameter(this, "model");
3840 compiler.parameter(this, "parametrization");
3841 compiler.add(this, "node_principled_hair_bsdf");
3842}
3843
3844/* Hair BSDF Closure */
3845
3847{
3848 NodeType *type = NodeType::add("hair_bsdf", create, NodeType::SHADER);
3849
3850 SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3851 SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3852
3853 static NodeEnum component_enum;
3854 component_enum.insert("reflection", CLOSURE_BSDF_HAIR_REFLECTION_ID);
3855 component_enum.insert("transmission", CLOSURE_BSDF_HAIR_TRANSMISSION_ID);
3856 SOCKET_ENUM(component, "Component", component_enum, CLOSURE_BSDF_HAIR_REFLECTION_ID);
3857 SOCKET_IN_FLOAT(offset, "Offset", 0.0f);
3858 SOCKET_IN_FLOAT(roughness_u, "RoughnessU", 0.2f);
3859 SOCKET_IN_FLOAT(roughness_v, "RoughnessV", 0.2f);
3860 SOCKET_IN_VECTOR(tangent, "Tangent", zero_float3());
3861
3862 SOCKET_OUT_CLOSURE(BSDF, "BSDF");
3863
3864 return type;
3865}
3866
3867HairBsdfNode::HairBsdfNode() : BsdfNode(get_node_type())
3868{
3870}
3871
3872void HairBsdfNode::compile(SVMCompiler &compiler)
3873{
3874 closure = component;
3875
3876 ShaderInput *tangent = input("Tangent");
3877 tangent = compiler.is_linked(tangent) ? tangent : nullptr;
3878
3880 compiler, input("RoughnessU"), input("RoughnessV"), input("Offset"), nullptr, tangent);
3881}
3882
3883void HairBsdfNode::compile(OSLCompiler &compiler)
3884{
3885 compiler.parameter(this, "component");
3886 compiler.add(this, "node_hair_bsdf");
3887}
3888
3889/* Geometry */
3890
3892{
3893 NodeType *type = NodeType::add("geometry", create, NodeType::SHADER);
3894
3895 SOCKET_OUT_POINT(position, "Position");
3896 SOCKET_OUT_NORMAL(normal, "Normal");
3897 SOCKET_OUT_NORMAL(tangent, "Tangent");
3898 SOCKET_OUT_NORMAL(true_normal, "True Normal");
3899 SOCKET_OUT_VECTOR(incoming, "Incoming");
3900 SOCKET_OUT_POINT(parametric, "Parametric");
3901 SOCKET_OUT_FLOAT(backfacing, "Backfacing");
3902 SOCKET_OUT_FLOAT(pointiness, "Pointiness");
3903 SOCKET_OUT_FLOAT(random_per_island, "Random Per Island");
3904
3905 return type;
3906}
3907
3908GeometryNode::GeometryNode() : ShaderNode(get_node_type())
3909{
3910 special_type = SHADER_SPECIAL_TYPE_GEOMETRY;
3911}
3912
3914{
3915 if (shader->has_surface_link()) {
3916 if (!output("Tangent")->links.empty()) {
3917 attributes->add(ATTR_STD_GENERATED);
3918 }
3919 if (!output("Pointiness")->links.empty()) {
3920 attributes->add(ATTR_STD_POINTINESS);
3921 }
3922 if (!output("Random Per Island")->links.empty()) {
3923 attributes->add(ATTR_STD_RANDOM_PER_ISLAND);
3924 }
3925 }
3926
3927 ShaderNode::attributes(shader, attributes);
3928}
3929
3930void GeometryNode::compile(SVMCompiler &compiler)
3931{
3932 ShaderOutput *out;
3933 ShaderNodeType geom_node = NODE_GEOMETRY;
3934 ShaderNodeType attr_node = NODE_ATTR;
3935
3936 if (bump == SHADER_BUMP_DX) {
3937 geom_node = NODE_GEOMETRY_BUMP_DX;
3938 attr_node = NODE_ATTR_BUMP_DX;
3939 }
3940 else if (bump == SHADER_BUMP_DY) {
3941 geom_node = NODE_GEOMETRY_BUMP_DY;
3942 attr_node = NODE_ATTR_BUMP_DY;
3943 }
3944
3945 out = output("Position");
3946 if (!out->links.empty()) {
3947 compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out));
3948 }
3949
3950 out = output("Normal");
3951 if (!out->links.empty()) {
3952 compiler.add_node(geom_node, NODE_GEOM_N, compiler.stack_assign(out));
3953 }
3954
3955 out = output("Tangent");
3956 if (!out->links.empty()) {
3957 compiler.add_node(geom_node, NODE_GEOM_T, compiler.stack_assign(out));
3958 }
3959
3960 out = output("True Normal");
3961 if (!out->links.empty()) {
3962 compiler.add_node(geom_node, NODE_GEOM_Ng, compiler.stack_assign(out));
3963 }
3964
3965 out = output("Incoming");
3966 if (!out->links.empty()) {
3967 compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out));
3968 }
3969
3970 out = output("Parametric");
3971 if (!out->links.empty()) {
3972 compiler.add_node(geom_node, NODE_GEOM_uv, compiler.stack_assign(out));
3973 }
3974
3975 out = output("Backfacing");
3976 if (!out->links.empty()) {
3977 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_backfacing, compiler.stack_assign(out));
3978 }
3979
3980 out = output("Pointiness");
3981 if (!out->links.empty()) {
3982 if (compiler.output_type() != SHADER_TYPE_VOLUME) {
3983 compiler.add_node(
3984 attr_node, ATTR_STD_POINTINESS, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
3985 }
3986 else {
3987 compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out));
3988 }
3989 }
3990
3991 out = output("Random Per Island");
3992 if (!out->links.empty()) {
3993 if (compiler.output_type() != SHADER_TYPE_VOLUME) {
3994 compiler.add_node(attr_node,
3996 compiler.stack_assign(out),
3998 }
3999 else {
4000 compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out));
4001 }
4002 }
4003}
4004
4005void GeometryNode::compile(OSLCompiler &compiler)
4006{
4007 if (bump == SHADER_BUMP_DX) {
4008 compiler.parameter("bump_offset", "dx");
4009 }
4010 else if (bump == SHADER_BUMP_DY) {
4011 compiler.parameter("bump_offset", "dy");
4012 }
4013 else {
4014 compiler.parameter("bump_offset", "center");
4015 }
4016
4017 compiler.add(this, "node_geometry");
4018}
4019
4020/* TextureCoordinate */
4021
4023{
4024 NodeType *type = NodeType::add("texture_coordinate", create, NodeType::SHADER);
4025
4026 SOCKET_BOOLEAN(from_dupli, "From Dupli", false);
4027 SOCKET_BOOLEAN(use_transform, "Use Transform", false);
4028 SOCKET_TRANSFORM(ob_tfm, "Object Transform", transform_identity());
4029
4030 SOCKET_OUT_POINT(generated, "Generated");
4031 SOCKET_OUT_NORMAL(normal, "Normal");
4032 SOCKET_OUT_POINT(UV, "UV");
4033 SOCKET_OUT_POINT(object, "Object");
4034 SOCKET_OUT_POINT(camera, "Camera");
4035 SOCKET_OUT_POINT(window, "Window");
4036 SOCKET_OUT_NORMAL(reflection, "Reflection");
4037
4038 return type;
4039}
4040
4041TextureCoordinateNode::TextureCoordinateNode() : ShaderNode(get_node_type()) {}
4042
4044{
4045 if (shader->has_surface_link()) {
4046 if (!from_dupli) {
4047 if (!output("Generated")->links.empty()) {
4048 attributes->add(ATTR_STD_GENERATED);
4049 }
4050 if (!output("UV")->links.empty()) {
4051 attributes->add(ATTR_STD_UV);
4052 }
4053 }
4054 }
4055
4056 if (shader->has_volume) {
4057 if (!from_dupli) {
4058 if (!output("Generated")->links.empty()) {
4059 attributes->add(ATTR_STD_GENERATED_TRANSFORM);
4060 }
4061 }
4062 }
4063
4064 ShaderNode::attributes(shader, attributes);
4065}
4066
4068{
4069 ShaderOutput *out;
4070 ShaderNodeType texco_node = NODE_TEX_COORD;
4071 ShaderNodeType attr_node = NODE_ATTR;
4072 ShaderNodeType geom_node = NODE_GEOMETRY;
4073
4074 if (bump == SHADER_BUMP_DX) {
4075 texco_node = NODE_TEX_COORD_BUMP_DX;
4076 attr_node = NODE_ATTR_BUMP_DX;
4077 geom_node = NODE_GEOMETRY_BUMP_DX;
4078 }
4079 else if (bump == SHADER_BUMP_DY) {
4080 texco_node = NODE_TEX_COORD_BUMP_DY;
4081 attr_node = NODE_ATTR_BUMP_DY;
4082 geom_node = NODE_GEOMETRY_BUMP_DY;
4083 }
4084
4085 out = output("Generated");
4086 if (!out->links.empty()) {
4087 if (compiler.background) {
4088 compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out));
4089 }
4090 else {
4091 if (from_dupli) {
4092 compiler.add_node(texco_node, NODE_TEXCO_DUPLI_GENERATED, compiler.stack_assign(out));
4093 }
4094 else if (compiler.output_type() == SHADER_TYPE_VOLUME) {
4095 compiler.add_node(texco_node, NODE_TEXCO_VOLUME_GENERATED, compiler.stack_assign(out));
4096 }
4097 else {
4098 int attr = compiler.attribute(ATTR_STD_GENERATED);
4099 compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3);
4100 }
4101 }
4102 }
4103
4104 out = output("Normal");
4105 if (!out->links.empty()) {
4106 compiler.add_node(texco_node, NODE_TEXCO_NORMAL, compiler.stack_assign(out));
4107 }
4108
4109 out = output("UV");
4110 if (!out->links.empty()) {
4111 if (from_dupli) {
4112 compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
4113 }
4114 else {
4115 int attr = compiler.attribute(ATTR_STD_UV);
4116 compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3);
4117 }
4118 }
4119
4120 out = output("Object");
4121 if (!out->links.empty()) {
4122 compiler.add_node(texco_node, NODE_TEXCO_OBJECT, compiler.stack_assign(out), use_transform);
4123 if (use_transform) {
4124 Transform ob_itfm = transform_inverse(ob_tfm);
4125 compiler.add_node(ob_itfm.x);
4126 compiler.add_node(ob_itfm.y);
4127 compiler.add_node(ob_itfm.z);
4128 }
4129 }
4130
4131 out = output("Camera");
4132 if (!out->links.empty()) {
4133 compiler.add_node(texco_node, NODE_TEXCO_CAMERA, compiler.stack_assign(out));
4134 }
4135
4136 out = output("Window");
4137 if (!out->links.empty()) {
4138 compiler.add_node(texco_node, NODE_TEXCO_WINDOW, compiler.stack_assign(out));
4139 }
4140
4141 out = output("Reflection");
4142 if (!out->links.empty()) {
4143 if (compiler.background) {
4144 compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out));
4145 }
4146 else {
4147 compiler.add_node(texco_node, NODE_TEXCO_REFLECTION, compiler.stack_assign(out));
4148 }
4149 }
4150}
4151
4153{
4154 if (bump == SHADER_BUMP_DX) {
4155 compiler.parameter("bump_offset", "dx");
4156 }
4157 else if (bump == SHADER_BUMP_DY) {
4158 compiler.parameter("bump_offset", "dy");
4159 }
4160 else {
4161 compiler.parameter("bump_offset", "center");
4162 }
4163
4164 if (compiler.background) {
4165 compiler.parameter("is_background", true);
4166 }
4167 if (compiler.output_type() == SHADER_TYPE_VOLUME) {
4168 compiler.parameter("is_volume", true);
4169 }
4170 compiler.parameter(this, "use_transform");
4171 Transform ob_itfm = transform_inverse(ob_tfm);
4172 compiler.parameter("object_itfm", ob_itfm);
4173
4174 compiler.parameter(this, "from_dupli");
4175
4176 compiler.add(this, "node_texture_coordinate");
4177}
4178
4179/* UV Map */
4180
4182{
4183 NodeType *type = NodeType::add("uvmap", create, NodeType::SHADER);
4184
4185 SOCKET_STRING(attribute, "attribute", ustring());
4186 SOCKET_IN_BOOLEAN(from_dupli, "from dupli", false);
4187
4188 SOCKET_OUT_POINT(UV, "UV");
4189
4190 return type;
4191}
4192
4193UVMapNode::UVMapNode() : ShaderNode(get_node_type()) {}
4194
4196{
4197 if (shader->has_surface) {
4198 if (!from_dupli) {
4199 if (!output("UV")->links.empty()) {
4200 if (attribute != "") {
4201 attributes->add(attribute);
4202 }
4203 else {
4204 attributes->add(ATTR_STD_UV);
4205 }
4206 }
4207 }
4208 }
4209
4210 ShaderNode::attributes(shader, attributes);
4211}
4212
4213void UVMapNode::compile(SVMCompiler &compiler)
4214{
4215 ShaderOutput *out = output("UV");
4216 ShaderNodeType texco_node = NODE_TEX_COORD;
4217 ShaderNodeType attr_node = NODE_ATTR;
4218 int attr;
4219
4220 if (bump == SHADER_BUMP_DX) {
4221 texco_node = NODE_TEX_COORD_BUMP_DX;
4222 attr_node = NODE_ATTR_BUMP_DX;
4223 }
4224 else if (bump == SHADER_BUMP_DY) {
4225 texco_node = NODE_TEX_COORD_BUMP_DY;
4226 attr_node = NODE_ATTR_BUMP_DY;
4227 }
4228
4229 if (!out->links.empty()) {
4230 if (from_dupli) {
4231 compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
4232 }
4233 else {
4234 if (attribute != "") {
4235 attr = compiler.attribute(attribute);
4236 }
4237 else {
4238 attr = compiler.attribute(ATTR_STD_UV);
4239 }
4240
4241 compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3);
4242 }
4243 }
4244}
4245
4246void UVMapNode::compile(OSLCompiler &compiler)
4247{
4248 if (bump == SHADER_BUMP_DX) {
4249 compiler.parameter("bump_offset", "dx");
4250 }
4251 else if (bump == SHADER_BUMP_DY) {
4252 compiler.parameter("bump_offset", "dy");
4253 }
4254 else {
4255 compiler.parameter("bump_offset", "center");
4256 }
4257
4258 compiler.parameter(this, "from_dupli");
4259 compiler.parameter(this, "attribute");
4260 compiler.add(this, "node_uv_map");
4261}
4262
4263/* Light Path */
4264
4266{
4267 NodeType *type = NodeType::add("light_path", create, NodeType::SHADER);
4268
4269 SOCKET_OUT_FLOAT(is_camera_ray, "Is Camera Ray");
4270 SOCKET_OUT_FLOAT(is_shadow_ray, "Is Shadow Ray");
4271 SOCKET_OUT_FLOAT(is_diffuse_ray, "Is Diffuse Ray");
4272 SOCKET_OUT_FLOAT(is_glossy_ray, "Is Glossy Ray");
4273 SOCKET_OUT_FLOAT(is_singular_ray, "Is Singular Ray");
4274 SOCKET_OUT_FLOAT(is_reflection_ray, "Is Reflection Ray");
4275 SOCKET_OUT_FLOAT(is_transmission_ray, "Is Transmission Ray");
4276 SOCKET_OUT_FLOAT(is_volume_scatter_ray, "Is Volume Scatter Ray");
4277 SOCKET_OUT_FLOAT(ray_length, "Ray Length");
4278 SOCKET_OUT_FLOAT(ray_depth, "Ray Depth");
4279 SOCKET_OUT_FLOAT(diffuse_depth, "Diffuse Depth");
4280 SOCKET_OUT_FLOAT(glossy_depth, "Glossy Depth");
4281 SOCKET_OUT_FLOAT(transparent_depth, "Transparent Depth");
4282 SOCKET_OUT_FLOAT(transmission_depth, "Transmission Depth");
4283
4284 return type;
4285}
4286
4287LightPathNode::LightPathNode() : ShaderNode(get_node_type()) {}
4288
4289void LightPathNode::compile(SVMCompiler &compiler)
4290{
4291 ShaderOutput *out;
4292
4293 out = output("Is Camera Ray");
4294 if (!out->links.empty()) {
4295 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_camera, compiler.stack_assign(out));
4296 }
4297
4298 out = output("Is Shadow Ray");
4299 if (!out->links.empty()) {
4300 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_shadow, compiler.stack_assign(out));
4301 }
4302
4303 out = output("Is Diffuse Ray");
4304 if (!out->links.empty()) {
4305 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_diffuse, compiler.stack_assign(out));
4306 }
4307
4308 out = output("Is Glossy Ray");
4309 if (!out->links.empty()) {
4310 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_glossy, compiler.stack_assign(out));
4311 }
4312
4313 out = output("Is Singular Ray");
4314 if (!out->links.empty()) {
4315 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_singular, compiler.stack_assign(out));
4316 }
4317
4318 out = output("Is Reflection Ray");
4319 if (!out->links.empty()) {
4320 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_reflection, compiler.stack_assign(out));
4321 }
4322
4323 out = output("Is Transmission Ray");
4324 if (!out->links.empty()) {
4325 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_transmission, compiler.stack_assign(out));
4326 }
4327
4328 out = output("Is Volume Scatter Ray");
4329 if (!out->links.empty()) {
4330 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_volume_scatter, compiler.stack_assign(out));
4331 }
4332
4333 out = output("Ray Length");
4334 if (!out->links.empty()) {
4335 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_length, compiler.stack_assign(out));
4336 }
4337
4338 out = output("Ray Depth");
4339 if (!out->links.empty()) {
4340 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_depth, compiler.stack_assign(out));
4341 }
4342
4343 out = output("Diffuse Depth");
4344 if (!out->links.empty()) {
4345 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_diffuse, compiler.stack_assign(out));
4346 }
4347
4348 out = output("Glossy Depth");
4349 if (!out->links.empty()) {
4350 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_glossy, compiler.stack_assign(out));
4351 }
4352
4353 out = output("Transparent Depth");
4354 if (!out->links.empty()) {
4355 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transparent, compiler.stack_assign(out));
4356 }
4357
4358 out = output("Transmission Depth");
4359 if (!out->links.empty()) {
4360 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transmission, compiler.stack_assign(out));
4361 }
4362}
4363
4364void LightPathNode::compile(OSLCompiler &compiler)
4365{
4366 compiler.add(this, "node_light_path");
4367}
4368
4369/* Light Falloff */
4370
4372{
4373 NodeType *type = NodeType::add("light_falloff", create, NodeType::SHADER);
4374
4375 SOCKET_IN_FLOAT(strength, "Strength", 100.0f);
4376 SOCKET_IN_FLOAT(smooth, "Smooth", 0.0f);
4377
4378 SOCKET_OUT_FLOAT(quadratic, "Quadratic");
4379 SOCKET_OUT_FLOAT(linear, "Linear");
4380 SOCKET_OUT_FLOAT(constant, "Constant");
4381
4382 return type;
4383}
4384
4385LightFalloffNode::LightFalloffNode() : ShaderNode(get_node_type()) {}
4386
4388{
4389 ShaderInput *strength_in = input("Strength");
4390 ShaderInput *smooth_in = input("Smooth");
4391
4392 ShaderOutput *out = output("Quadratic");
4393 if (!out->links.empty()) {
4394 compiler.add_node(NODE_LIGHT_FALLOFF,
4396 compiler.encode_uchar4(compiler.stack_assign(strength_in),
4397 compiler.stack_assign(smooth_in),
4398 compiler.stack_assign(out)));
4399 }
4400
4401 out = output("Linear");
4402 if (!out->links.empty()) {
4403 compiler.add_node(NODE_LIGHT_FALLOFF,
4405 compiler.encode_uchar4(compiler.stack_assign(strength_in),
4406 compiler.stack_assign(smooth_in),
4407 compiler.stack_assign(out)));
4408 }
4409
4410 out = output("Constant");
4411 if (!out->links.empty()) {
4412 compiler.add_node(NODE_LIGHT_FALLOFF,
4414 compiler.encode_uchar4(compiler.stack_assign(strength_in),
4415 compiler.stack_assign(smooth_in),
4416 compiler.stack_assign(out)));
4417 }
4418}
4419
4421{
4422 compiler.add(this, "node_light_falloff");
4423}
4424
4425/* Object Info */
4426
4428{
4429 NodeType *type = NodeType::add("object_info", create, NodeType::SHADER);
4430
4431 SOCKET_OUT_VECTOR(location, "Location");
4432 SOCKET_OUT_COLOR(color, "Color");
4433 SOCKET_OUT_FLOAT(alpha, "Alpha");
4434 SOCKET_OUT_FLOAT(object_index, "Object Index");
4435 SOCKET_OUT_FLOAT(material_index, "Material Index");
4436 SOCKET_OUT_FLOAT(random, "Random");
4437
4438 return type;
4439}
4440
4441ObjectInfoNode::ObjectInfoNode() : ShaderNode(get_node_type()) {}
4442
4444{
4445 ShaderOutput *out = output("Location");
4446 if (!out->links.empty()) {
4447 compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_LOCATION, compiler.stack_assign(out));
4448 }
4449
4450 out = output("Color");
4451 if (!out->links.empty()) {
4452 compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_COLOR, compiler.stack_assign(out));
4453 }
4454
4455 out = output("Alpha");
4456 if (!out->links.empty()) {
4457 compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_ALPHA, compiler.stack_assign(out));
4458 }
4459
4460 out = output("Object Index");
4461 if (!out->links.empty()) {
4462 compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_INDEX, compiler.stack_assign(out));
4463 }
4464
4465 out = output("Material Index");
4466 if (!out->links.empty()) {
4467 compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_MAT_INDEX, compiler.stack_assign(out));
4468 }
4469
4470 out = output("Random");
4471 if (!out->links.empty()) {
4472 compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_RANDOM, compiler.stack_assign(out));
4473 }
4474}
4475
4477{
4478 compiler.add(this, "node_object_info");
4479}
4480
4481/* Particle Info */
4482
4484{
4485 NodeType *type = NodeType::add("particle_info", create, NodeType::SHADER);
4486
4487 SOCKET_OUT_FLOAT(index, "Index");
4488 SOCKET_OUT_FLOAT(random, "Random");
4489 SOCKET_OUT_FLOAT(age, "Age");
4490 SOCKET_OUT_FLOAT(lifetime, "Lifetime");
4491 SOCKET_OUT_POINT(location, "Location");
4492#if 0 /* not yet supported */
4493 SOCKET_OUT_QUATERNION(rotation, "Rotation");
4494#endif
4495 SOCKET_OUT_FLOAT(size, "Size");
4496 SOCKET_OUT_VECTOR(velocity, "Velocity");
4497 SOCKET_OUT_VECTOR(angular_velocity, "Angular Velocity");
4498
4499 return type;
4500}
4501
4502ParticleInfoNode::ParticleInfoNode() : ShaderNode(get_node_type()) {}
4503
4505{
4506 if (!output("Index")->links.empty()) {
4507 attributes->add(ATTR_STD_PARTICLE);
4508 }
4509 if (!output("Random")->links.empty()) {
4510 attributes->add(ATTR_STD_PARTICLE);
4511 }
4512 if (!output("Age")->links.empty()) {
4513 attributes->add(ATTR_STD_PARTICLE);
4514 }
4515 if (!output("Lifetime")->links.empty()) {
4516 attributes->add(ATTR_STD_PARTICLE);
4517 }
4518 if (!output("Location")->links.empty()) {
4519 attributes->add(ATTR_STD_PARTICLE);
4520 }
4521#if 0 /* not yet supported */
4522 if (!output("Rotation")->links.empty())
4523 attributes->add(ATTR_STD_PARTICLE);
4524#endif
4525 if (!output("Size")->links.empty()) {
4526 attributes->add(ATTR_STD_PARTICLE);
4527 }
4528 if (!output("Velocity")->links.empty()) {
4529 attributes->add(ATTR_STD_PARTICLE);
4530 }
4531 if (!output("Angular Velocity")->links.empty()) {
4532 attributes->add(ATTR_STD_PARTICLE);
4533 }
4534
4535 ShaderNode::attributes(shader, attributes);
4536}
4537
4539{
4540 ShaderOutput *out;
4541
4542 out = output("Index");
4543 if (!out->links.empty()) {
4544 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, compiler.stack_assign(out));
4545 }
4546
4547 out = output("Random");
4548 if (!out->links.empty()) {
4549 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_RANDOM, compiler.stack_assign(out));
4550 }
4551
4552 out = output("Age");
4553 if (!out->links.empty()) {
4554 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_AGE, compiler.stack_assign(out));
4555 }
4556
4557 out = output("Lifetime");
4558 if (!out->links.empty()) {
4559 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LIFETIME, compiler.stack_assign(out));
4560 }
4561
4562 out = output("Location");
4563 if (!out->links.empty()) {
4564 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, compiler.stack_assign(out));
4565 }
4566
4567 /* quaternion data is not yet supported by Cycles */
4568#if 0
4569 out = output("Rotation");
4570 if (!out->links.empty()) {
4571 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, compiler.stack_assign(out));
4572 }
4573#endif
4574
4575 out = output("Size");
4576 if (!out->links.empty()) {
4577 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_SIZE, compiler.stack_assign(out));
4578 }
4579
4580 out = output("Velocity");
4581 if (!out->links.empty()) {
4582 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_VELOCITY, compiler.stack_assign(out));
4583 }
4584
4585 out = output("Angular Velocity");
4586 if (!out->links.empty()) {
4587 compiler.add_node(
4588 NODE_PARTICLE_INFO, NODE_INFO_PAR_ANGULAR_VELOCITY, compiler.stack_assign(out));
4589 }
4590}
4591
4593{
4594 compiler.add(this, "node_particle_info");
4595}
4596
4597/* Hair Info */
4598
4600{
4601 NodeType *type = NodeType::add("hair_info", create, NodeType::SHADER);
4602
4603 SOCKET_OUT_FLOAT(is_strand, "Is Strand");
4604 SOCKET_OUT_FLOAT(intercept, "Intercept");
4605 SOCKET_OUT_FLOAT(size, "Length");
4606 SOCKET_OUT_FLOAT(thickness, "Thickness");
4607 SOCKET_OUT_NORMAL(tangent_normal, "Tangent Normal");
4608 SOCKET_OUT_FLOAT(index, "Random");
4609
4610 return type;
4611}
4612
4613HairInfoNode::HairInfoNode() : ShaderNode(get_node_type()) {}
4614
4616{
4617 if (shader->has_surface_link()) {
4618 ShaderOutput *intercept_out = output("Intercept");
4619
4620 if (!intercept_out->links.empty()) {
4621 attributes->add(ATTR_STD_CURVE_INTERCEPT);
4622 }
4623
4624 if (!output("Length")->links.empty()) {
4625 attributes->add(ATTR_STD_CURVE_LENGTH);
4626 }
4627
4628 if (!output("Random")->links.empty()) {
4629 attributes->add(ATTR_STD_CURVE_RANDOM);
4630 }
4631 }
4632
4633 ShaderNode::attributes(shader, attributes);
4634}
4635
4636void HairInfoNode::compile(SVMCompiler &compiler)
4637{
4638 ShaderOutput *out;
4639
4640 out = output("Is Strand");
4641 if (!out->links.empty()) {
4642 compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_IS_STRAND, compiler.stack_assign(out));
4643 }
4644
4645 out = output("Intercept");
4646 if (!out->links.empty()) {
4647 int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT);
4648 compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
4649 }
4650
4651 out = output("Length");
4652 if (!out->links.empty()) {
4653 int attr = compiler.attribute(ATTR_STD_CURVE_LENGTH);
4654 compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
4655 }
4656
4657 out = output("Thickness");
4658 if (!out->links.empty()) {
4659 compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_THICKNESS, compiler.stack_assign(out));
4660 }
4661
4662 out = output("Tangent Normal");
4663 if (!out->links.empty()) {
4664 compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, compiler.stack_assign(out));
4665 }
4666
4667 out = output("Random");
4668 if (!out->links.empty()) {
4669 int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM);
4670 compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
4671 }
4672}
4673
4674void HairInfoNode::compile(OSLCompiler &compiler)
4675{
4676 compiler.add(this, "node_hair_info");
4677}
4678
4679/* Point Info */
4680
4682{
4683 NodeType *type = NodeType::add("point_info", create, NodeType::SHADER);
4684
4685 SOCKET_OUT_POINT(position, "Position");
4686 SOCKET_OUT_FLOAT(radius, "Radius");
4687 SOCKET_OUT_FLOAT(random, "Random");
4688
4689 return type;
4690}
4691
4692PointInfoNode::PointInfoNode() : ShaderNode(get_node_type()) {}
4693
4695{
4696 if (shader->has_surface_link()) {
4697 if (!output("Random")->links.empty()) {
4698 attributes->add(ATTR_STD_POINT_RANDOM);
4699 }
4700 }
4701
4702 ShaderNode::attributes(shader, attributes);
4703}
4704
4705void PointInfoNode::compile(SVMCompiler &compiler)
4706{
4707 ShaderOutput *out;
4708
4709 out = output("Position");
4710 if (!out->links.empty()) {
4711 compiler.add_node(NODE_POINT_INFO, NODE_INFO_POINT_POSITION, compiler.stack_assign(out));
4712 }
4713
4714 out = output("Radius");
4715 if (!out->links.empty()) {
4716 compiler.add_node(NODE_POINT_INFO, NODE_INFO_POINT_RADIUS, compiler.stack_assign(out));
4717 }
4718
4719 out = output("Random");
4720 if (!out->links.empty()) {
4721 int attr = compiler.attribute(ATTR_STD_POINT_RANDOM);
4722 compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
4723 }
4724}
4725
4726void PointInfoNode::compile(OSLCompiler &compiler)
4727{
4728 compiler.add(this, "node_point_info");
4729}
4730
4731/* Volume Info */
4732
4734{
4735 NodeType *type = NodeType::add("volume_info", create, NodeType::SHADER);
4736
4737 SOCKET_OUT_COLOR(color, "Color");
4738 SOCKET_OUT_FLOAT(density, "Density");
4739 SOCKET_OUT_FLOAT(flame, "Flame");
4740 SOCKET_OUT_FLOAT(temperature, "Temperature");
4741
4742 return type;
4743}
4744
4745VolumeInfoNode::VolumeInfoNode() : ShaderNode(get_node_type()) {}
4746
4747/* The requested attributes are not updated after node expansion.
4748 * So we explicitly request the required attributes.
4749 */
4751{
4752 if (shader->has_volume) {
4753 if (!output("Color")->links.empty()) {
4754 attributes->add(ATTR_STD_VOLUME_COLOR);
4755 }
4756 if (!output("Density")->links.empty()) {
4757 attributes->add(ATTR_STD_VOLUME_DENSITY);
4758 }
4759 if (!output("Flame")->links.empty()) {
4760 attributes->add(ATTR_STD_VOLUME_FLAME);
4761 }
4762 if (!output("Temperature")->links.empty()) {
4763 attributes->add(ATTR_STD_VOLUME_TEMPERATURE);
4764 }
4765 attributes->add(ATTR_STD_GENERATED_TRANSFORM);
4766 }
4767 ShaderNode::attributes(shader, attributes);
4768}
4769
4771{
4772 ShaderOutput *color_out = output("Color");
4773 if (!color_out->links.empty()) {
4774 AttributeNode *attr = graph->create_node<AttributeNode>();
4775 attr->set_attribute(ustring("color"));
4776 graph->add(attr);
4777 graph->relink(color_out, attr->output("Color"));
4778 }
4779
4780 ShaderOutput *density_out = output("Density");
4781 if (!density_out->links.empty()) {
4782 AttributeNode *attr = graph->create_node<AttributeNode>();
4783 attr->set_attribute(ustring("density"));
4784 graph->add(attr);
4785 graph->relink(density_out, attr->output("Fac"));
4786 }
4787
4788 ShaderOutput *flame_out = output("Flame");
4789 if (!flame_out->links.empty()) {
4790 AttributeNode *attr = graph->create_node<AttributeNode>();
4791 attr->set_attribute(ustring("flame"));
4792 graph->add(attr);
4793 graph->relink(flame_out, attr->output("Fac"));
4794 }
4795
4796 ShaderOutput *temperature_out = output("Temperature");
4797 if (!temperature_out->links.empty()) {
4798 AttributeNode *attr = graph->create_node<AttributeNode>();
4799 attr->set_attribute(ustring("temperature"));
4800 graph->add(attr);
4801 graph->relink(temperature_out, attr->output("Fac"));
4802 }
4803}
4804
4806
4808
4810{
4811 NodeType *type = NodeType::add("vertex_color", create, NodeType::SHADER);
4812
4813 SOCKET_STRING(layer_name, "Layer Name", ustring());
4814 SOCKET_OUT_COLOR(color, "Color");
4815 SOCKET_OUT_FLOAT(alpha, "Alpha");
4816
4817 return type;
4818}
4819
4820VertexColorNode::VertexColorNode() : ShaderNode(get_node_type()) {}
4821
4823{
4824 if (!(output("Color")->links.empty() && output("Alpha")->links.empty())) {
4825 if (layer_name != "") {
4826 attributes->add_standard(layer_name);
4827 }
4828 else {
4829 attributes->add(ATTR_STD_VERTEX_COLOR);
4830 }
4831 }
4832 ShaderNode::attributes(shader, attributes);
4833}
4834
4836{
4837 ShaderOutput *color_out = output("Color");
4838 ShaderOutput *alpha_out = output("Alpha");
4839 int layer_id = 0;
4840
4841 if (layer_name != "") {
4842 layer_id = compiler.attribute(layer_name);
4843 }
4844 else {
4845 layer_id = compiler.attribute(ATTR_STD_VERTEX_COLOR);
4846 }
4847
4849
4850 if (bump == SHADER_BUMP_DX) {
4851 node = NODE_VERTEX_COLOR_BUMP_DX;
4852 }
4853 else if (bump == SHADER_BUMP_DY) {
4854 node = NODE_VERTEX_COLOR_BUMP_DY;
4855 }
4856 else {
4857 node = NODE_VERTEX_COLOR;
4858 }
4859
4860 compiler.add_node(
4861 node, layer_id, compiler.stack_assign(color_out), compiler.stack_assign(alpha_out));
4862}
4863
4865{
4866 if (bump == SHADER_BUMP_DX) {
4867 compiler.parameter("bump_offset", "dx");
4868 }
4869 else if (bump == SHADER_BUMP_DY) {
4870 compiler.parameter("bump_offset", "dy");
4871 }
4872 else {
4873 compiler.parameter("bump_offset", "center");
4874 }
4875
4876 if (layer_name.empty()) {
4877 compiler.parameter("layer_name", ustring("geom:vertex_color"));
4878 }
4879 else {
4880 if (Attribute::name_standard(layer_name.c_str()) != ATTR_STD_NONE) {
4881 compiler.parameter("name", (string("geom:") + layer_name.c_str()).c_str());
4882 }
4883 else {
4884 compiler.parameter("layer_name", layer_name.c_str());
4885 }
4886 }
4887
4888 compiler.add(this, "node_vertex_color");
4889}
4890
4891/* Value */
4892
4894{
4895 NodeType *type = NodeType::add("value", create, NodeType::SHADER);
4896
4897 SOCKET_FLOAT(value, "Value", 0.0f);
4898 SOCKET_OUT_FLOAT(value, "Value");
4899
4900 return type;
4901}
4902
4903ValueNode::ValueNode() : ShaderNode(get_node_type()) {}
4904
4906{
4907 folder.make_constant(value);
4908}
4909
4910void ValueNode::compile(SVMCompiler &compiler)
4911{
4912 ShaderOutput *val_out = output("Value");
4913
4914 compiler.add_node(NODE_VALUE_F, __float_as_int(value), compiler.stack_assign(val_out));
4915}
4916
4917void ValueNode::compile(OSLCompiler &compiler)
4918{
4919 compiler.parameter("value_value", value);
4920 compiler.add(this, "node_value");
4921}
4922
4923/* Color */
4924
4926{
4927 NodeType *type = NodeType::add("color", create, NodeType::SHADER);
4928
4929 SOCKET_COLOR(value, "Value", zero_float3());
4930 SOCKET_OUT_COLOR(color, "Color");
4931
4932 return type;
4933}
4934
4935ColorNode::ColorNode() : ShaderNode(get_node_type()) {}
4936
4938{
4939 folder.make_constant(value);
4940}
4941
4942void ColorNode::compile(SVMCompiler &compiler)
4943{
4944 ShaderOutput *color_out = output("Color");
4945
4946 if (!color_out->links.empty()) {
4947 compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
4948 compiler.add_node(NODE_VALUE_V, value);
4949 }
4950}
4951
4952void ColorNode::compile(OSLCompiler &compiler)
4953{
4954 compiler.parameter_color("color_value", value);
4955
4956 compiler.add(this, "node_value");
4957}
4958
4959/* Add Closure */
4960
4962{
4963 NodeType *type = NodeType::add("add_closure", create, NodeType::SHADER);
4964
4965 SOCKET_IN_CLOSURE(closure1, "Closure1");
4966 SOCKET_IN_CLOSURE(closure2, "Closure2");
4967 SOCKET_OUT_CLOSURE(closure, "Closure");
4968
4969 return type;
4970}
4971
4972AddClosureNode::AddClosureNode() : ShaderNode(get_node_type())
4973{
4975}
4976
4977void AddClosureNode::compile(SVMCompiler & /*compiler*/)
4978{
4979 /* handled in the SVM compiler */
4980}
4981
4983{
4984 compiler.add(this, "node_add_closure");
4985}
4986
4988{
4989 ShaderInput *closure1_in = input("Closure1");
4990 ShaderInput *closure2_in = input("Closure2");
4991
4992 /* remove useless add closures nodes */
4993 if (!closure1_in->link) {
4994 folder.bypass_or_discard(closure2_in);
4995 }
4996 else if (!closure2_in->link) {
4997 folder.bypass_or_discard(closure1_in);
4998 }
4999}
5000
5001/* Mix Closure */
5002
5004{
5005 NodeType *type = NodeType::add("mix_closure", create, NodeType::SHADER);
5006
5007 SOCKET_IN_FLOAT(fac, "Fac", 0.5f);
5008 SOCKET_IN_CLOSURE(closure1, "Closure1");
5009 SOCKET_IN_CLOSURE(closure2, "Closure2");
5010
5011 SOCKET_OUT_CLOSURE(closure, "Closure");
5012
5013 return type;
5014}
5015
5016MixClosureNode::MixClosureNode() : ShaderNode(get_node_type())
5017{
5019}
5020
5021void MixClosureNode::compile(SVMCompiler & /*compiler*/)
5022{
5023 /* handled in the SVM compiler */
5024}
5025
5027{
5028 compiler.add(this, "node_mix_closure");
5029}
5030
5032{
5033 ShaderInput *fac_in = input("Fac");
5034 ShaderInput *closure1_in = input("Closure1");
5035 ShaderInput *closure2_in = input("Closure2");
5036
5037 /* remove useless mix closures nodes */
5038 if (closure1_in->link == closure2_in->link) {
5039 folder.bypass_or_discard(closure1_in);
5040 }
5041 /* remove unused mix closure input when factor is 0.0 or 1.0
5042 * check for closure links and make sure factor link is disconnected */
5043 else if (!fac_in->link) {
5044 /* factor 0.0 */
5045 if (fac <= 0.0f) {
5046 folder.bypass_or_discard(closure1_in);
5047 }
5048 /* factor 1.0 */
5049 else if (fac >= 1.0f) {
5050 folder.bypass_or_discard(closure2_in);
5051 }
5052 }
5053}
5054
5055/* Mix Closure */
5056
5058{
5059 NodeType *type = NodeType::add("mix_closure_weight", create, NodeType::SHADER);
5060
5061 SOCKET_IN_FLOAT(weight, "Weight", 1.0f);
5062 SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
5063
5064 SOCKET_OUT_FLOAT(weight1, "Weight1");
5065 SOCKET_OUT_FLOAT(weight2, "Weight2");
5066
5067 return type;
5068}
5069
5070MixClosureWeightNode::MixClosureWeightNode() : ShaderNode(get_node_type()) {}
5071
5073{
5074 ShaderInput *weight_in = input("Weight");
5075 ShaderInput *fac_in = input("Fac");
5076 ShaderOutput *weight1_out = output("Weight1");
5077 ShaderOutput *weight2_out = output("Weight2");
5078
5079 compiler.add_node(NODE_MIX_CLOSURE,
5080 compiler.encode_uchar4(compiler.stack_assign(fac_in),
5081 compiler.stack_assign(weight_in),
5082 compiler.stack_assign(weight1_out),
5083 compiler.stack_assign(weight2_out)));
5084}
5085
5086void MixClosureWeightNode::compile(OSLCompiler & /*compiler*/)
5087{
5088 assert(0);
5089}
5090
5091/* Invert */
5092
5094{
5095 NodeType *type = NodeType::add("invert", create, NodeType::SHADER);
5096
5097 SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
5098 SOCKET_IN_COLOR(color, "Color", zero_float3());
5099
5100 SOCKET_OUT_COLOR(color, "Color");
5101
5102 return type;
5103}
5104
5105InvertNode::InvertNode() : ShaderNode(get_node_type()) {}
5106
5108{
5109 ShaderInput *fac_in = input("Fac");
5110 ShaderInput *color_in = input("Color");
5111
5112 if (!fac_in->link) {
5113 /* evaluate fully constant node */
5114 if (!color_in->link) {
5115 folder.make_constant(interp(color, one_float3() - color, fac));
5116 }
5117 /* remove no-op node */
5118 else if (fac == 0.0f) {
5119 folder.bypass(color_in->link);
5120 }
5121 }
5122}
5123
5124void InvertNode::compile(SVMCompiler &compiler)
5125{
5126 ShaderInput *fac_in = input("Fac");
5127 ShaderInput *color_in = input("Color");
5128 ShaderOutput *color_out = output("Color");
5129
5130 compiler.add_node(NODE_INVERT,
5131 compiler.stack_assign(fac_in),
5132 compiler.stack_assign(color_in),
5133 compiler.stack_assign(color_out));
5134}
5135
5136void InvertNode::compile(OSLCompiler &compiler)
5137{
5138 compiler.add(this, "node_invert");
5139}
5140
5141/* Mix */
5142
5144{
5145 NodeType *type = NodeType::add("mix", create, NodeType::SHADER);
5146
5147 static NodeEnum type_enum;
5148 type_enum.insert("mix", NODE_MIX_BLEND);
5149 type_enum.insert("add", NODE_MIX_ADD);
5150 type_enum.insert("multiply", NODE_MIX_MUL);
5151 type_enum.insert("screen", NODE_MIX_SCREEN);
5152 type_enum.insert("overlay", NODE_MIX_OVERLAY);
5153 type_enum.insert("subtract", NODE_MIX_SUB);
5154 type_enum.insert("divide", NODE_MIX_DIV);
5155 type_enum.insert("difference", NODE_MIX_DIFF);
5156 type_enum.insert("darken", NODE_MIX_DARK);
5157 type_enum.insert("lighten", NODE_MIX_LIGHT);
5158 type_enum.insert("dodge", NODE_MIX_DODGE);
5159 type_enum.insert("burn", NODE_MIX_BURN);
5160 type_enum.insert("hue", NODE_MIX_HUE);
5161 type_enum.insert("saturation", NODE_MIX_SAT);
5162 type_enum.insert("value", NODE_MIX_VAL);
5163 type_enum.insert("color", NODE_MIX_COL);
5164 type_enum.insert("soft_light", NODE_MIX_SOFT);
5165 type_enum.insert("linear_light", NODE_MIX_LINEAR);
5166 type_enum.insert("exclusion", NODE_MIX_EXCLUSION);
5167 SOCKET_ENUM(mix_type, "Type", type_enum, NODE_MIX_BLEND);
5168
5169 SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
5170
5171 SOCKET_IN_FLOAT(fac, "Fac", 0.5f);
5172 SOCKET_IN_COLOR(color1, "Color1", zero_float3());
5173 SOCKET_IN_COLOR(color2, "Color2", zero_float3());
5174
5175 SOCKET_OUT_COLOR(color, "Color");
5176
5177 return type;
5178}
5179
5180MixNode::MixNode() : ShaderNode(get_node_type()) {}
5181
5182void MixNode::compile(SVMCompiler &compiler)
5183{
5184 ShaderInput *fac_in = input("Fac");
5185 ShaderInput *color1_in = input("Color1");
5186 ShaderInput *color2_in = input("Color2");
5187 ShaderOutput *color_out = output("Color");
5188
5189 compiler.add_node(NODE_MIX,
5190 compiler.stack_assign(fac_in),
5191 compiler.stack_assign(color1_in),
5192 compiler.stack_assign(color2_in));
5193 compiler.add_node(NODE_MIX, mix_type, compiler.stack_assign(color_out));
5194
5195 if (use_clamp) {
5196 compiler.add_node(NODE_MIX, 0, compiler.stack_assign(color_out));
5197 compiler.add_node(NODE_MIX, NODE_MIX_CLAMP, compiler.stack_assign(color_out));
5198 }
5199}
5200
5201void MixNode::compile(OSLCompiler &compiler)
5202{
5203 compiler.parameter(this, "mix_type");
5204 compiler.parameter(this, "use_clamp");
5205 compiler.add(this, "node_mix");
5206}
5207
5209{
5210 if (folder.all_inputs_constant()) {
5211 folder.make_constant_clamp(svm_mix_clamped_factor(mix_type, fac, color1, color2), use_clamp);
5212 }
5213 else {
5214 folder.fold_mix(mix_type, use_clamp);
5215 }
5216}
5217
5218/* Mix Color */
5219
5221{
5222 NodeType *type = NodeType::add("mix_color", create, NodeType::SHADER);
5223
5224 static NodeEnum type_enum;
5225 type_enum.insert("mix", NODE_MIX_BLEND);
5226 type_enum.insert("add", NODE_MIX_ADD);
5227 type_enum.insert("multiply", NODE_MIX_MUL);
5228 type_enum.insert("screen", NODE_MIX_SCREEN);
5229 type_enum.insert("overlay", NODE_MIX_OVERLAY);
5230 type_enum.insert("subtract", NODE_MIX_SUB);
5231 type_enum.insert("divide", NODE_MIX_DIV);
5232 type_enum.insert("difference", NODE_MIX_DIFF);
5233 type_enum.insert("darken", NODE_MIX_DARK);
5234 type_enum.insert("lighten", NODE_MIX_LIGHT);
5235 type_enum.insert("dodge", NODE_MIX_DODGE);
5236 type_enum.insert("burn", NODE_MIX_BURN);
5237 type_enum.insert("hue", NODE_MIX_HUE);
5238 type_enum.insert("saturation", NODE_MIX_SAT);
5239 type_enum.insert("value", NODE_MIX_VAL);
5240 type_enum.insert("color", NODE_MIX_COL);
5241 type_enum.insert("soft_light", NODE_MIX_SOFT);
5242 type_enum.insert("linear_light", NODE_MIX_LINEAR);
5243 type_enum.insert("exclusion", NODE_MIX_EXCLUSION);
5244 SOCKET_ENUM(blend_type, "Type", type_enum, NODE_MIX_BLEND);
5245
5246 SOCKET_IN_FLOAT(fac, "Factor", 0.5f);
5247 SOCKET_IN_COLOR(a, "A", zero_float3());
5248 SOCKET_IN_COLOR(b, "B", zero_float3());
5249 SOCKET_BOOLEAN(use_clamp_result, "Use Clamp Result", false);
5250 SOCKET_BOOLEAN(use_clamp, "Use Clamp", true);
5251
5252 SOCKET_OUT_COLOR(result, "Result");
5253
5254 return type;
5255}
5256
5257MixColorNode::MixColorNode() : ShaderNode(get_node_type()) {}
5258
5259void MixColorNode::compile(SVMCompiler &compiler)
5260{
5261 ShaderInput *fac_in = input("Factor");
5262 ShaderInput *a_in = input("A");
5263 ShaderInput *b_in = input("B");
5264 ShaderOutput *result_out = output("Result");
5265
5266 int fac_in_stack_offset = compiler.stack_assign(fac_in);
5267 int a_in_stack_offset = compiler.stack_assign(a_in);
5268 int b_in_stack_offset = compiler.stack_assign(b_in);
5269
5270 compiler.add_node(
5271 NODE_MIX_COLOR,
5272 compiler.encode_uchar4(use_clamp, blend_type, use_clamp_result),
5273 compiler.encode_uchar4(fac_in_stack_offset, a_in_stack_offset, b_in_stack_offset),
5274 compiler.stack_assign(result_out));
5275}
5276
5277void MixColorNode::compile(OSLCompiler &compiler)
5278{
5279 compiler.parameter(this, "blend_type");
5280 compiler.parameter(this, "use_clamp");
5281 compiler.parameter(this, "use_clamp_result");
5282 compiler.add(this, "node_mix_color");
5283}
5284
5286{
5287 if (folder.all_inputs_constant()) {
5288 if (use_clamp) {
5289 fac = clamp(fac, 0.0f, 1.0f);
5290 }
5291 folder.make_constant_clamp(svm_mix(blend_type, fac, a, b), use_clamp_result);
5292 }
5293 else {
5294 folder.fold_mix_color(blend_type, use_clamp, use_clamp_result);
5295 }
5296}
5297
5298/* Mix Float */
5299
5301{
5302 NodeType *type = NodeType::add("mix_float", create, NodeType::SHADER);
5303
5304 SOCKET_IN_FLOAT(fac, "Factor", 0.5f);
5305 SOCKET_IN_FLOAT(a, "A", 0.0f);
5306 SOCKET_IN_FLOAT(b, "B", 0.0f);
5307 SOCKET_BOOLEAN(use_clamp, "Use Clamp", true);
5308 SOCKET_OUT_FLOAT(result, "Result");
5309
5310 return type;
5311}
5312
5313MixFloatNode::MixFloatNode() : ShaderNode(get_node_type()) {}
5314
5315void MixFloatNode::compile(SVMCompiler &compiler)
5316{
5317 ShaderInput *fac_in = input("Factor");
5318 ShaderInput *a_in = input("A");
5319 ShaderInput *b_in = input("B");
5320 ShaderOutput *result_out = output("Result");
5321
5322 int fac_in_stack_offset = compiler.stack_assign(fac_in);
5323 int a_in_stack_offset = compiler.stack_assign(a_in);
5324 int b_in_stack_offset = compiler.stack_assign(b_in);
5325
5326 compiler.add_node(
5327 NODE_MIX_FLOAT,
5328 use_clamp,
5329 compiler.encode_uchar4(fac_in_stack_offset, a_in_stack_offset, b_in_stack_offset),
5330 compiler.stack_assign(result_out));
5331}
5332
5333void MixFloatNode::compile(OSLCompiler &compiler)
5334{
5335 compiler.parameter(this, "use_clamp");
5336 compiler.add(this, "node_mix_float");
5337}
5338
5340{
5341 if (folder.all_inputs_constant()) {
5342 if (use_clamp) {
5343 fac = clamp(fac, 0.0f, 1.0f);
5344 }
5345 folder.make_constant(a * (1 - fac) + b * fac);
5346 }
5347 else {
5348 folder.fold_mix_float(use_clamp, false);
5349 }
5350}
5351
5352/* Mix Vector */
5353
5355{
5356 NodeType *type = NodeType::add("mix_vector", create, NodeType::SHADER);
5357
5358 SOCKET_IN_FLOAT(fac, "Factor", 0.5f);
5359 SOCKET_IN_VECTOR(a, "A", zero_float3());
5361 SOCKET_BOOLEAN(use_clamp, "Use Clamp", true);
5362
5363 SOCKET_OUT_VECTOR(result, "Result");
5364
5365 return type;
5366}
5367
5368MixVectorNode::MixVectorNode() : ShaderNode(get_node_type()) {}
5369
5370void MixVectorNode::compile(SVMCompiler &compiler)
5371{
5372 ShaderInput *fac_in = input("Factor");
5373 ShaderInput *a_in = input("A");
5374 ShaderInput *b_in = input("B");
5375 ShaderOutput *result_out = output("Result");
5376
5377 int fac_in_stack_offset = compiler.stack_assign(fac_in);
5378 int a_in_stack_offset = compiler.stack_assign(a_in);
5379 int b_in_stack_offset = compiler.stack_assign(b_in);
5380
5381 compiler.add_node(
5382 NODE_MIX_VECTOR,
5383 compiler.encode_uchar4(use_clamp, fac_in_stack_offset, a_in_stack_offset, b_in_stack_offset),
5384 compiler.stack_assign(result_out));
5385}
5386
5387void MixVectorNode::compile(OSLCompiler &compiler)
5388{
5389 compiler.parameter(this, "use_clamp");
5390 compiler.add(this, "node_mix_vector");
5391}
5392
5394{
5395 if (folder.all_inputs_constant()) {
5396 if (use_clamp) {
5397 fac = clamp(fac, 0.0f, 1.0f);
5398 }
5399 folder.make_constant(a * (one_float3() - fac) + b * fac);
5400 }
5401 else {
5402 folder.fold_mix_color(NODE_MIX_BLEND, use_clamp, false);
5403 }
5404}
5405
5406/* Mix Vector Non Uniform */
5407
5409{
5410 NodeType *type = NodeType::add("mix_vector_non_uniform", create, NodeType::SHADER);
5411
5412 SOCKET_IN_VECTOR(fac, "Factor", make_float3(0.5f, 0.5f, 0.5f));
5413 SOCKET_IN_VECTOR(a, "A", zero_float3());
5415 SOCKET_BOOLEAN(use_clamp, "Use Clamp", true);
5416
5417 SOCKET_OUT_VECTOR(result, "Result");
5418
5419 return type;
5420}
5421
5422MixVectorNonUniformNode::MixVectorNonUniformNode() : ShaderNode(get_node_type()) {}
5423
5425{
5426 ShaderInput *fac_in = input("Factor");
5427 ShaderInput *a_in = input("A");
5428 ShaderInput *b_in = input("B");
5429 ShaderOutput *result_out = output("Result");
5430
5431 int fac_in_stack_offset = compiler.stack_assign(fac_in);
5432 int a_in_stack_offset = compiler.stack_assign(a_in);
5433 int b_in_stack_offset = compiler.stack_assign(b_in);
5434
5435 compiler.add_node(
5436 NODE_MIX_VECTOR_NON_UNIFORM,
5437 compiler.encode_uchar4(use_clamp, fac_in_stack_offset, a_in_stack_offset, b_in_stack_offset),
5438 compiler.stack_assign(result_out));
5439}
5440
5442{
5443 compiler.parameter(this, "use_clamp");
5444 compiler.add(this, "node_mix_vector_non_uniform");
5445}
5446
5448{
5449 if (folder.all_inputs_constant()) {
5450 if (use_clamp) {
5451 fac = saturate(fac);
5452 }
5453 folder.make_constant(a * (one_float3() - fac) + b * fac);
5454 }
5455}
5456
5457/* Combine Color */
5458
5460{
5461 NodeType *type = NodeType::add("combine_color", create, NodeType::SHADER);
5462
5463 static NodeEnum type_enum;
5464 type_enum.insert("rgb", NODE_COMBSEP_COLOR_RGB);
5465 type_enum.insert("hsv", NODE_COMBSEP_COLOR_HSV);
5466 type_enum.insert("hsl", NODE_COMBSEP_COLOR_HSL);
5467 SOCKET_ENUM(color_type, "Type", type_enum, NODE_COMBSEP_COLOR_RGB);
5468
5469 SOCKET_IN_FLOAT(r, "Red", 0.0f);
5470 SOCKET_IN_FLOAT(g, "Green", 0.0f);
5471 SOCKET_IN_FLOAT(b, "Blue", 0.0f);
5472
5473 SOCKET_OUT_COLOR(color, "Color");
5474
5475 return type;
5476}
5477
5478CombineColorNode::CombineColorNode() : ShaderNode(get_node_type()) {}
5479
5481{
5482 if (folder.all_inputs_constant()) {
5483 folder.make_constant(svm_combine_color(color_type, make_float3(r, g, b)));
5484 }
5485}
5486
5488{
5489 ShaderInput *red_in = input("Red");
5490 ShaderInput *green_in = input("Green");
5491 ShaderInput *blue_in = input("Blue");
5492 ShaderOutput *color_out = output("Color");
5493
5494 int red_stack_offset = compiler.stack_assign(red_in);
5495 int green_stack_offset = compiler.stack_assign(green_in);
5496 int blue_stack_offset = compiler.stack_assign(blue_in);
5497 int color_stack_offset = compiler.stack_assign(color_out);
5498
5499 compiler.add_node(
5500 NODE_COMBINE_COLOR,
5501 color_type,
5502 compiler.encode_uchar4(red_stack_offset, green_stack_offset, blue_stack_offset),
5503 color_stack_offset);
5504}
5505
5507{
5508 compiler.parameter(this, "color_type");
5509 compiler.add(this, "node_combine_color");
5510}
5511
5512/* Combine RGB */
5513
5515{
5516 NodeType *type = NodeType::add("combine_rgb", create, NodeType::SHADER);
5517
5518 SOCKET_IN_FLOAT(r, "R", 0.0f);
5519 SOCKET_IN_FLOAT(g, "G", 0.0f);
5520 SOCKET_IN_FLOAT(b, "B", 0.0f);
5521
5522 SOCKET_OUT_COLOR(image, "Image");
5523
5524 return type;
5525}
5526
5527CombineRGBNode::CombineRGBNode() : ShaderNode(get_node_type()) {}
5528
5530{
5531 if (folder.all_inputs_constant()) {
5532 folder.make_constant(make_float3(r, g, b));
5533 }
5534}
5535
5537{
5538 ShaderInput *red_in = input("R");
5539 ShaderInput *green_in = input("G");
5540 ShaderInput *blue_in = input("B");
5541 ShaderOutput *color_out = output("Image");
5542
5543 compiler.add_node(
5544 NODE_COMBINE_VECTOR, compiler.stack_assign(red_in), 0, compiler.stack_assign(color_out));
5545
5546 compiler.add_node(
5547 NODE_COMBINE_VECTOR, compiler.stack_assign(green_in), 1, compiler.stack_assign(color_out));
5548
5549 compiler.add_node(
5550 NODE_COMBINE_VECTOR, compiler.stack_assign(blue_in), 2, compiler.stack_assign(color_out));
5551}
5552
5554{
5555 compiler.add(this, "node_combine_rgb");
5556}
5557
5558/* Combine XYZ */
5559
5561{
5562 NodeType *type = NodeType::add("combine_xyz", create, NodeType::SHADER);
5563
5564 SOCKET_IN_FLOAT(x, "X", 0.0f);
5565 SOCKET_IN_FLOAT(y, "Y", 0.0f);
5566 SOCKET_IN_FLOAT(z, "Z", 0.0f);
5567
5568 SOCKET_OUT_VECTOR(vector, "Vector");
5569
5570 return type;
5571}
5572
5573CombineXYZNode::CombineXYZNode() : ShaderNode(get_node_type()) {}
5574
5576{
5577 if (folder.all_inputs_constant()) {
5578 folder.make_constant(make_float3(x, y, z));
5579 }
5580}
5581
5583{
5584 ShaderInput *x_in = input("X");
5585 ShaderInput *y_in = input("Y");
5586 ShaderInput *z_in = input("Z");
5587 ShaderOutput *vector_out = output("Vector");
5588
5589 compiler.add_node(
5590 NODE_COMBINE_VECTOR, compiler.stack_assign(x_in), 0, compiler.stack_assign(vector_out));
5591
5592 compiler.add_node(
5593 NODE_COMBINE_VECTOR, compiler.stack_assign(y_in), 1, compiler.stack_assign(vector_out));
5594
5595 compiler.add_node(
5596 NODE_COMBINE_VECTOR, compiler.stack_assign(z_in), 2, compiler.stack_assign(vector_out));
5597}
5598
5600{
5601 compiler.add(this, "node_combine_xyz");
5602}
5603
5604/* Combine HSV */
5605
5607{
5608 NodeType *type = NodeType::add("combine_hsv", create, NodeType::SHADER);
5609
5610 SOCKET_IN_FLOAT(h, "H", 0.0f);
5611 SOCKET_IN_FLOAT(s, "S", 0.0f);
5612 SOCKET_IN_FLOAT(v, "V", 0.0f);
5613
5614 SOCKET_OUT_COLOR(color, "Color");
5615
5616 return type;
5617}
5618
5619CombineHSVNode::CombineHSVNode() : ShaderNode(get_node_type()) {}
5620
5622{
5623 if (folder.all_inputs_constant()) {
5624 folder.make_constant(hsv_to_rgb(make_float3(h, s, v)));
5625 }
5626}
5627
5629{
5630 ShaderInput *hue_in = input("H");
5631 ShaderInput *saturation_in = input("S");
5632 ShaderInput *value_in = input("V");
5633 ShaderOutput *color_out = output("Color");
5634
5635 compiler.add_node(NODE_COMBINE_HSV,
5636 compiler.stack_assign(hue_in),
5637 compiler.stack_assign(saturation_in),
5638 compiler.stack_assign(value_in));
5639 compiler.add_node(NODE_COMBINE_HSV, compiler.stack_assign(color_out));
5640}
5641
5643{
5644 compiler.add(this, "node_combine_hsv");
5645}
5646
5647/* Gamma */
5648
5650{
5651 NodeType *type = NodeType::add("gamma", create, NodeType::SHADER);
5652
5653 SOCKET_IN_COLOR(color, "Color", zero_float3());
5654 SOCKET_IN_FLOAT(gamma, "Gamma", 1.0f);
5655 SOCKET_OUT_COLOR(color, "Color");
5656
5657 return type;
5658}
5659
5660GammaNode::GammaNode() : ShaderNode(get_node_type()) {}
5661
5663{
5664 if (folder.all_inputs_constant()) {
5665 folder.make_constant(svm_math_gamma_color(color, gamma));
5666 }
5667 else {
5668 ShaderInput *color_in = input("Color");
5669 ShaderInput *gamma_in = input("Gamma");
5670
5671 /* 1 ^ X == X ^ 0 == 1 */
5672 if (folder.is_one(color_in) || folder.is_zero(gamma_in)) {
5673 folder.make_one();
5674 }
5675 /* X ^ 1 == X */
5676 else if (folder.is_one(gamma_in)) {
5677 folder.try_bypass_or_make_constant(color_in, false);
5678 }
5679 }
5680}
5681
5682void GammaNode::compile(SVMCompiler &compiler)
5683{
5684 ShaderInput *color_in = input("Color");
5685 ShaderInput *gamma_in = input("Gamma");
5686 ShaderOutput *color_out = output("Color");
5687
5688 compiler.add_node(NODE_GAMMA,
5689 compiler.stack_assign(gamma_in),
5690 compiler.stack_assign(color_in),
5691 compiler.stack_assign(color_out));
5692}
5693
5694void GammaNode::compile(OSLCompiler &compiler)
5695{
5696 compiler.add(this, "node_gamma");
5697}
5698
5699/* Bright Contrast */
5700
5702{
5703 NodeType *type = NodeType::add("brightness_contrast", create, NodeType::SHADER);
5704
5705 SOCKET_IN_COLOR(color, "Color", zero_float3());
5706 SOCKET_IN_FLOAT(bright, "Bright", 0.0f);
5707 SOCKET_IN_FLOAT(contrast, "Contrast", 0.0f);
5708
5709 SOCKET_OUT_COLOR(color, "Color");
5710
5711 return type;
5712}
5713
5714BrightContrastNode::BrightContrastNode() : ShaderNode(get_node_type()) {}
5715
5717{
5718 if (folder.all_inputs_constant()) {
5719 folder.make_constant(svm_brightness_contrast(color, bright, contrast));
5720 }
5721}
5722
5724{
5725 ShaderInput *color_in = input("Color");
5726 ShaderInput *bright_in = input("Bright");
5727 ShaderInput *contrast_in = input("Contrast");
5728 ShaderOutput *color_out = output("Color");
5729
5730 compiler.add_node(NODE_BRIGHTCONTRAST,
5731 compiler.stack_assign(color_in),
5732 compiler.stack_assign(color_out),
5733 compiler.encode_uchar4(compiler.stack_assign(bright_in),
5734 compiler.stack_assign(contrast_in)));
5735}
5736
5738{
5739 compiler.add(this, "node_brightness");
5740}
5741
5742/* Separate Color */
5743
5745{
5746 NodeType *type = NodeType::add("separate_color", create, NodeType::SHADER);
5747
5748 static NodeEnum type_enum;
5749 type_enum.insert("rgb", NODE_COMBSEP_COLOR_RGB);
5750 type_enum.insert("hsv", NODE_COMBSEP_COLOR_HSV);
5751 type_enum.insert("hsl", NODE_COMBSEP_COLOR_HSL);
5752 SOCKET_ENUM(color_type, "Type", type_enum, NODE_COMBSEP_COLOR_RGB);
5753
5754 SOCKET_IN_COLOR(color, "Color", zero_float3());
5755
5756 SOCKET_OUT_FLOAT(r, "Red");
5757 SOCKET_OUT_FLOAT(g, "Green");
5758 SOCKET_OUT_FLOAT(b, "Blue");
5759
5760 return type;
5761}
5762
5763SeparateColorNode::SeparateColorNode() : ShaderNode(get_node_type()) {}
5764
5766{
5767 if (folder.all_inputs_constant()) {
5768 float3 col = svm_separate_color(color_type, color);
5769
5770 for (int channel = 0; channel < 3; channel++) {
5771 if (outputs[channel] == folder.output) {
5772 folder.make_constant(col[channel]);
5773 return;
5774 }
5775 }
5776 }
5777}
5778
5780{
5781 ShaderInput *color_in = input("Color");
5782 ShaderOutput *red_out = output("Red");
5783 ShaderOutput *green_out = output("Green");
5784 ShaderOutput *blue_out = output("Blue");
5785
5786 int color_stack_offset = compiler.stack_assign(color_in);
5787 int red_stack_offset = compiler.stack_assign(red_out);
5788 int green_stack_offset = compiler.stack_assign(green_out);
5789 int blue_stack_offset = compiler.stack_assign(blue_out);
5790
5791 compiler.add_node(
5792 NODE_SEPARATE_COLOR,
5793 color_type,
5794 color_stack_offset,
5795 compiler.encode_uchar4(red_stack_offset, green_stack_offset, blue_stack_offset));
5796}
5797
5799{
5800 compiler.parameter(this, "color_type");
5801 compiler.add(this, "node_separate_color");
5802}
5803
5804/* Separate RGB */
5805
5807{
5808 NodeType *type = NodeType::add("separate_rgb", create, NodeType::SHADER);
5809
5810 SOCKET_IN_COLOR(color, "Image", zero_float3());
5811
5812 SOCKET_OUT_FLOAT(r, "R");
5813 SOCKET_OUT_FLOAT(g, "G");
5814 SOCKET_OUT_FLOAT(b, "B");
5815
5816 return type;
5817}
5818
5819SeparateRGBNode::SeparateRGBNode() : ShaderNode(get_node_type()) {}
5820
5822{
5823 if (folder.all_inputs_constant()) {
5824 for (int channel = 0; channel < 3; channel++) {
5825 if (outputs[channel] == folder.output) {
5826 folder.make_constant(color[channel]);
5827 return;
5828 }
5829 }
5830 }
5831}
5832
5834{
5835 ShaderInput *color_in = input("Image");
5836 ShaderOutput *red_out = output("R");
5837 ShaderOutput *green_out = output("G");
5838 ShaderOutput *blue_out = output("B");
5839
5840 compiler.add_node(
5841 NODE_SEPARATE_VECTOR, compiler.stack_assign(color_in), 0, compiler.stack_assign(red_out));
5842
5843 compiler.add_node(
5844 NODE_SEPARATE_VECTOR, compiler.stack_assign(color_in), 1, compiler.stack_assign(green_out));
5845
5846 compiler.add_node(
5847 NODE_SEPARATE_VECTOR, compiler.stack_assign(color_in), 2, compiler.stack_assign(blue_out));
5848}
5849
5851{
5852 compiler.add(this, "node_separate_rgb");
5853}
5854
5855/* Separate XYZ */
5856
5858{
5859 NodeType *type = NodeType::add("separate_xyz", create, NodeType::SHADER);
5860
5861 SOCKET_IN_COLOR(vector, "Vector", zero_float3());
5862
5863 SOCKET_OUT_FLOAT(x, "X");
5864 SOCKET_OUT_FLOAT(y, "Y");
5865 SOCKET_OUT_FLOAT(z, "Z");
5866
5867 return type;
5868}
5869
5870SeparateXYZNode::SeparateXYZNode() : ShaderNode(get_node_type()) {}
5871
5873{
5874 if (folder.all_inputs_constant()) {
5875 for (int channel = 0; channel < 3; channel++) {
5876 if (outputs[channel] == folder.output) {
5877 folder.make_constant(vector[channel]);
5878 return;
5879 }
5880 }
5881 }
5882}
5883
5885{
5886 ShaderInput *vector_in = input("Vector");
5887 ShaderOutput *x_out = output("X");
5888 ShaderOutput *y_out = output("Y");
5889 ShaderOutput *z_out = output("Z");
5890
5891 compiler.add_node(
5892 NODE_SEPARATE_VECTOR, compiler.stack_assign(vector_in), 0, compiler.stack_assign(x_out));
5893
5894 compiler.add_node(
5895 NODE_SEPARATE_VECTOR, compiler.stack_assign(vector_in), 1, compiler.stack_assign(y_out));
5896
5897 compiler.add_node(
5898 NODE_SEPARATE_VECTOR, compiler.stack_assign(vector_in), 2, compiler.stack_assign(z_out));
5899}
5900
5902{
5903 compiler.add(this, "node_separate_xyz");
5904}
5905
5906/* Separate HSV */
5907
5909{
5910 NodeType *type = NodeType::add("separate_hsv", create, NodeType::SHADER);
5911
5912 SOCKET_IN_COLOR(color, "Color", zero_float3());
5913
5914 SOCKET_OUT_FLOAT(h, "H");
5915 SOCKET_OUT_FLOAT(s, "S");
5916 SOCKET_OUT_FLOAT(v, "V");
5917
5918 return type;
5919}
5920
5921SeparateHSVNode::SeparateHSVNode() : ShaderNode(get_node_type()) {}
5922
5924{
5925 if (folder.all_inputs_constant()) {
5926 float3 hsv = rgb_to_hsv(color);
5927
5928 for (int channel = 0; channel < 3; channel++) {
5929 if (outputs[channel] == folder.output) {
5930 folder.make_constant(hsv[channel]);
5931 return;
5932 }
5933 }
5934 }
5935}
5936
5938{
5939 ShaderInput *color_in = input("Color");
5940 ShaderOutput *hue_out = output("H");
5941 ShaderOutput *saturation_out = output("S");
5942 ShaderOutput *value_out = output("V");
5943
5944 compiler.add_node(NODE_SEPARATE_HSV,
5945 compiler.stack_assign(color_in),
5946 compiler.stack_assign(hue_out),
5947 compiler.stack_assign(saturation_out));
5948 compiler.add_node(NODE_SEPARATE_HSV, compiler.stack_assign(value_out));
5949}
5950
5952{
5953 compiler.add(this, "node_separate_hsv");
5954}
5955
5956/* Hue/Saturation/Value */
5957
5959{
5960 NodeType *type = NodeType::add("hsv", create, NodeType::SHADER);
5961
5962 SOCKET_IN_FLOAT(hue, "Hue", 0.5f);
5963 SOCKET_IN_FLOAT(saturation, "Saturation", 1.0f);
5964 SOCKET_IN_FLOAT(value, "Value", 1.0f);
5965 SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
5966 SOCKET_IN_COLOR(color, "Color", zero_float3());
5967
5968 SOCKET_OUT_COLOR(color, "Color");
5969
5970 return type;
5971}
5972
5973HSVNode::HSVNode() : ShaderNode(get_node_type()) {}
5974
5975void HSVNode::compile(SVMCompiler &compiler)
5976{
5977 ShaderInput *hue_in = input("Hue");
5978 ShaderInput *saturation_in = input("Saturation");
5979 ShaderInput *value_in = input("Value");
5980 ShaderInput *fac_in = input("Fac");
5981 ShaderInput *color_in = input("Color");
5982 ShaderOutput *color_out = output("Color");
5983
5984 compiler.add_node(NODE_HSV,
5985 compiler.encode_uchar4(compiler.stack_assign(color_in),
5986 compiler.stack_assign(fac_in),
5987 compiler.stack_assign(color_out)),
5988 compiler.encode_uchar4(compiler.stack_assign(hue_in),
5989 compiler.stack_assign(saturation_in),
5990 compiler.stack_assign(value_in)));
5991}
5992
5993void HSVNode::compile(OSLCompiler &compiler)
5994{
5995 compiler.add(this, "node_hsv");
5996}
5997
5998/* Attribute */
5999
6001{
6002 NodeType *type = NodeType::add("attribute", create, NodeType::SHADER);
6003
6004 SOCKET_STRING(attribute, "Attribute", ustring());
6005
6006 SOCKET_OUT_COLOR(color, "Color");
6007 SOCKET_OUT_VECTOR(vector, "Vector");
6008 SOCKET_OUT_FLOAT(fac, "Fac");
6009 SOCKET_OUT_FLOAT(alpha, "Alpha");
6010
6011 return type;
6012}
6013
6014AttributeNode::AttributeNode() : ShaderNode(get_node_type()) {}
6015
6017{
6018 ShaderOutput *color_out = output("Color");
6019 ShaderOutput *vector_out = output("Vector");
6020 ShaderOutput *fac_out = output("Fac");
6021 ShaderOutput *alpha_out = output("Alpha");
6022
6023 if (!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty() ||
6024 !alpha_out->links.empty())
6025 {
6026 attributes->add_standard(attribute);
6027 }
6028
6029 if (shader->has_volume) {
6030 attributes->add(ATTR_STD_GENERATED_TRANSFORM);
6031 }
6032
6033 ShaderNode::attributes(shader, attributes);
6034}
6035
6036void AttributeNode::compile(SVMCompiler &compiler)
6037{
6038 ShaderOutput *color_out = output("Color");
6039 ShaderOutput *vector_out = output("Vector");
6040 ShaderOutput *fac_out = output("Fac");
6041 ShaderOutput *alpha_out = output("Alpha");
6042 ShaderNodeType attr_node = NODE_ATTR;
6043 int attr = compiler.attribute_standard(attribute);
6044
6045 if (bump == SHADER_BUMP_DX) {
6046 attr_node = NODE_ATTR_BUMP_DX;
6047 }
6048 else if (bump == SHADER_BUMP_DY) {
6049 attr_node = NODE_ATTR_BUMP_DY;
6050 }
6051
6052 if (!color_out->links.empty() || !vector_out->links.empty()) {
6053 if (!color_out->links.empty()) {
6054 compiler.add_node(
6055 attr_node, attr, compiler.stack_assign(color_out), NODE_ATTR_OUTPUT_FLOAT3);
6056 }
6057 if (!vector_out->links.empty()) {
6058 compiler.add_node(
6059 attr_node, attr, compiler.stack_assign(vector_out), NODE_ATTR_OUTPUT_FLOAT3);
6060 }
6061 }
6062
6063 if (!fac_out->links.empty()) {
6064 compiler.add_node(attr_node, attr, compiler.stack_assign(fac_out), NODE_ATTR_OUTPUT_FLOAT);
6065 }
6066
6067 if (!alpha_out->links.empty()) {
6068 compiler.add_node(
6069 attr_node, attr, compiler.stack_assign(alpha_out), NODE_ATTR_OUTPUT_FLOAT_ALPHA);
6070 }
6071}
6072
6073void AttributeNode::compile(OSLCompiler &compiler)
6074{
6075 if (bump == SHADER_BUMP_DX) {
6076 compiler.parameter("bump_offset", "dx");
6077 }
6078 else if (bump == SHADER_BUMP_DY) {
6079 compiler.parameter("bump_offset", "dy");
6080 }
6081 else {
6082 compiler.parameter("bump_offset", "center");
6083 }
6084
6085 if (Attribute::name_standard(attribute.c_str()) != ATTR_STD_NONE) {
6086 compiler.parameter("name", (string("geom:") + attribute.c_str()).c_str());
6087 }
6088 else {
6089 compiler.parameter("name", attribute.c_str());
6090 }
6091
6092 compiler.add(this, "node_attribute");
6093}
6094
6095/* Camera */
6096
6098{
6099 NodeType *type = NodeType::add("camera_info", create, NodeType::SHADER);
6100
6101 SOCKET_OUT_VECTOR(view_vector, "View Vector");
6102 SOCKET_OUT_FLOAT(view_z_depth, "View Z Depth");
6103 SOCKET_OUT_FLOAT(view_distance, "View Distance");
6104
6105 return type;
6106}
6107
6108CameraNode::CameraNode() : ShaderNode(get_node_type()) {}
6109
6110void CameraNode::compile(SVMCompiler &compiler)
6111{
6112 ShaderOutput *vector_out = output("View Vector");
6113 ShaderOutput *z_depth_out = output("View Z Depth");
6114 ShaderOutput *distance_out = output("View Distance");
6115
6116 compiler.add_node(NODE_CAMERA,
6117 compiler.stack_assign(vector_out),
6118 compiler.stack_assign(z_depth_out),
6119 compiler.stack_assign(distance_out));
6120}
6121
6122void CameraNode::compile(OSLCompiler &compiler)
6123{
6124 compiler.add(this, "node_camera");
6125}
6126
6127/* Fresnel */
6128
6130{
6131 NodeType *type = NodeType::add("fresnel", create, NodeType::SHADER);
6132
6135 SOCKET_IN_FLOAT(IOR, "IOR", 1.5f);
6136
6137 SOCKET_OUT_FLOAT(fac, "Fac");
6138
6139 return type;
6140}
6141
6142FresnelNode::FresnelNode() : ShaderNode(get_node_type()) {}
6143
6144void FresnelNode::compile(SVMCompiler &compiler)
6145{
6146 ShaderInput *normal_in = input("Normal");
6147 ShaderInput *IOR_in = input("IOR");
6148 ShaderOutput *fac_out = output("Fac");
6149
6150 compiler.add_node(NODE_FRESNEL,
6151 compiler.stack_assign(IOR_in),
6152 __float_as_int(IOR),
6153 compiler.encode_uchar4(compiler.stack_assign_if_linked(normal_in),
6154 compiler.stack_assign(fac_out)));
6155}
6156
6157void FresnelNode::compile(OSLCompiler &compiler)
6158{
6159 compiler.add(this, "node_fresnel");
6160}
6161
6162/* Layer Weight */
6163
6165{
6166 NodeType *type = NodeType::add("layer_weight", create, NodeType::SHADER);
6167
6170 SOCKET_IN_FLOAT(blend, "Blend", 0.5f);
6171
6172 SOCKET_OUT_FLOAT(fresnel, "Fresnel");
6173 SOCKET_OUT_FLOAT(facing, "Facing");
6174
6175 return type;
6176}
6177
6178LayerWeightNode::LayerWeightNode() : ShaderNode(get_node_type()) {}
6179
6181{
6182 ShaderInput *normal_in = input("Normal");
6183 ShaderInput *blend_in = input("Blend");
6184 ShaderOutput *fresnel_out = output("Fresnel");
6185 ShaderOutput *facing_out = output("Facing");
6186
6187 if (!fresnel_out->links.empty()) {
6188 compiler.add_node(NODE_LAYER_WEIGHT,
6189 compiler.stack_assign_if_linked(blend_in),
6192 compiler.stack_assign_if_linked(normal_in),
6193 compiler.stack_assign(fresnel_out)));
6194 }
6195
6196 if (!facing_out->links.empty()) {
6197 compiler.add_node(NODE_LAYER_WEIGHT,
6198 compiler.stack_assign_if_linked(blend_in),
6201 compiler.stack_assign_if_linked(normal_in),
6202 compiler.stack_assign(facing_out)));
6203 }
6204}
6205
6207{
6208 compiler.add(this, "node_layer_weight");
6209}
6210
6211/* Wireframe */
6212
6214{
6215 NodeType *type = NodeType::add("wireframe", create, NodeType::SHADER);
6216
6217 SOCKET_BOOLEAN(use_pixel_size, "Use Pixel Size", false);
6218 SOCKET_IN_FLOAT(size, "Size", 0.01f);
6219 SOCKET_OUT_FLOAT(fac, "Fac");
6220
6221 return type;
6222}
6223
6224WireframeNode::WireframeNode() : ShaderNode(get_node_type()) {}
6225
6226void WireframeNode::compile(SVMCompiler &compiler)
6227{
6228 ShaderInput *size_in = input("Size");
6229 ShaderOutput *fac_out = output("Fac");
6231 if (bump == SHADER_BUMP_DX) {
6232 bump_offset = NODE_BUMP_OFFSET_DX;
6233 }
6234 else if (bump == SHADER_BUMP_DY) {
6235 bump_offset = NODE_BUMP_OFFSET_DY;
6236 }
6237 compiler.add_node(NODE_WIREFRAME,
6238 compiler.stack_assign(size_in),
6239 compiler.stack_assign(fac_out),
6240 compiler.encode_uchar4(use_pixel_size, bump_offset, 0, 0));
6241}
6242
6243void WireframeNode::compile(OSLCompiler &compiler)
6244{
6245 if (bump == SHADER_BUMP_DX) {
6246 compiler.parameter("bump_offset", "dx");
6247 }
6248 else if (bump == SHADER_BUMP_DY) {
6249 compiler.parameter("bump_offset", "dy");
6250 }
6251 else {
6252 compiler.parameter("bump_offset", "center");
6253 }
6254 compiler.parameter(this, "use_pixel_size");
6255 compiler.add(this, "node_wireframe");
6256}
6257
6258/* Wavelength */
6259
6261{
6262 NodeType *type = NodeType::add("wavelength", create, NodeType::SHADER);
6263
6264 SOCKET_IN_FLOAT(wavelength, "Wavelength", 500.0f);
6265 SOCKET_OUT_COLOR(color, "Color");
6266
6267 return type;
6268}
6269
6270WavelengthNode::WavelengthNode() : ShaderNode(get_node_type()) {}
6271
6273{
6274 ShaderInput *wavelength_in = input("Wavelength");
6275 ShaderOutput *color_out = output("Color");
6276
6277 compiler.add_node(
6278 NODE_WAVELENGTH, compiler.stack_assign(wavelength_in), compiler.stack_assign(color_out));
6279}
6280
6282{
6283 compiler.add(this, "node_wavelength");
6284}
6285
6286/* Blackbody */
6287
6289{
6290 NodeType *type = NodeType::add("blackbody", create, NodeType::SHADER);
6291
6292 SOCKET_IN_FLOAT(temperature, "Temperature", 1200.0f);
6293 SOCKET_OUT_COLOR(color, "Color");
6294
6295 return type;
6296}
6297
6298BlackbodyNode::BlackbodyNode() : ShaderNode(get_node_type()) {}
6299
6301{
6302 if (folder.all_inputs_constant()) {
6303 const float3 rgb_rec709 = svm_math_blackbody_color_rec709(temperature);
6304 const float3 rgb = folder.scene->shader_manager->rec709_to_scene_linear(rgb_rec709);
6305 folder.make_constant(max(rgb, zero_float3()));
6306 }
6307}
6308
6309void BlackbodyNode::compile(SVMCompiler &compiler)
6310{
6311 ShaderInput *temperature_in = input("Temperature");
6312 ShaderOutput *color_out = output("Color");
6313
6314 compiler.add_node(
6315 NODE_BLACKBODY, compiler.stack_assign(temperature_in), compiler.stack_assign(color_out));
6316}
6317
6318void BlackbodyNode::compile(OSLCompiler &compiler)
6319{
6320 compiler.add(this, "node_blackbody");
6321}
6322
6323/* Output */
6324
6326{
6327 NodeType *type = NodeType::add("output", create, NodeType::SHADER);
6328
6329 SOCKET_IN_CLOSURE(surface, "Surface");
6330 SOCKET_IN_CLOSURE(volume, "Volume");
6331 SOCKET_IN_VECTOR(displacement, "Displacement", zero_float3());
6332 SOCKET_IN_NORMAL(normal, "Normal", zero_float3());
6333
6334 return type;
6335}
6336
6337OutputNode::OutputNode() : ShaderNode(get_node_type())
6338{
6339 special_type = SHADER_SPECIAL_TYPE_OUTPUT;
6340}
6341
6342void OutputNode::compile(SVMCompiler &compiler)
6343{
6344 if (compiler.output_type() == SHADER_TYPE_DISPLACEMENT) {
6345 ShaderInput *displacement_in = input("Displacement");
6346
6347 if (displacement_in->link) {
6348 compiler.add_node(NODE_SET_DISPLACEMENT, compiler.stack_assign(displacement_in));
6349 }
6350 }
6351}
6352
6353void OutputNode::compile(OSLCompiler &compiler)
6354{
6355 if (compiler.output_type() == SHADER_TYPE_SURFACE) {
6356 compiler.add(this, "node_output_surface");
6357 }
6358 else if (compiler.output_type() == SHADER_TYPE_VOLUME) {
6359 compiler.add(this, "node_output_volume");
6360 }
6361 else if (compiler.output_type() == SHADER_TYPE_DISPLACEMENT) {
6362 compiler.add(this, "node_output_displacement");
6363 }
6364}
6365
6366/* Map Range Node */
6367
6369{
6370 NodeType *type = NodeType::add("map_range", create, NodeType::SHADER);
6371
6372 static NodeEnum type_enum;
6373 type_enum.insert("linear", NODE_MAP_RANGE_LINEAR);
6374 type_enum.insert("stepped", NODE_MAP_RANGE_STEPPED);
6375 type_enum.insert("smoothstep", NODE_MAP_RANGE_SMOOTHSTEP);
6376 type_enum.insert("smootherstep", NODE_MAP_RANGE_SMOOTHERSTEP);
6377 SOCKET_ENUM(range_type, "Type", type_enum, NODE_MAP_RANGE_LINEAR);
6378
6379 SOCKET_IN_FLOAT(value, "Value", 1.0f);
6380 SOCKET_IN_FLOAT(from_min, "From Min", 0.0f);
6381 SOCKET_IN_FLOAT(from_max, "From Max", 1.0f);
6382 SOCKET_IN_FLOAT(to_min, "To Min", 0.0f);
6383 SOCKET_IN_FLOAT(to_max, "To Max", 1.0f);
6384 SOCKET_IN_FLOAT(steps, "Steps", 4.0f);
6385 SOCKET_IN_BOOLEAN(clamp, "Clamp", false);
6386
6387 SOCKET_OUT_FLOAT(result, "Result");
6388
6389 return type;
6390}
6391
6392MapRangeNode::MapRangeNode() : ShaderNode(get_node_type()) {}
6393
6395{
6396 if (clamp) {
6397 ShaderOutput *result_out = output("Result");
6398 if (!result_out->links.empty()) {
6399 ClampNode *clamp_node = graph->create_node<ClampNode>();
6400 clamp_node->set_clamp_type(NODE_CLAMP_RANGE);
6401 graph->add(clamp_node);
6402 graph->relink(result_out, clamp_node->output("Result"));
6403 graph->connect(result_out, clamp_node->input("Value"));
6404 if (input("To Min")->link) {
6405 graph->connect(input("To Min")->link, clamp_node->input("Min"));
6406 }
6407 else {
6408 clamp_node->set_min(to_min);
6409 }
6410 if (input("To Max")->link) {
6411 graph->connect(input("To Max")->link, clamp_node->input("Max"));
6412 }
6413 else {
6414 clamp_node->set_max(to_max);
6415 }
6416 }
6417 }
6418}
6419
6420void MapRangeNode::compile(SVMCompiler &compiler)
6421{
6422 ShaderInput *value_in = input("Value");
6423 ShaderInput *from_min_in = input("From Min");
6424 ShaderInput *from_max_in = input("From Max");
6425 ShaderInput *to_min_in = input("To Min");
6426 ShaderInput *to_max_in = input("To Max");
6427 ShaderInput *steps_in = input("Steps");
6428 ShaderOutput *result_out = output("Result");
6429
6430 int value_stack_offset = compiler.stack_assign(value_in);
6431 int from_min_stack_offset = compiler.stack_assign_if_linked(from_min_in);
6432 int from_max_stack_offset = compiler.stack_assign_if_linked(from_max_in);
6433 int to_min_stack_offset = compiler.stack_assign_if_linked(to_min_in);
6434 int to_max_stack_offset = compiler.stack_assign_if_linked(to_max_in);
6435 int steps_stack_offset = compiler.stack_assign(steps_in);
6436 int result_stack_offset = compiler.stack_assign(result_out);
6437
6438 compiler.add_node(
6439 NODE_MAP_RANGE,
6440 value_stack_offset,
6441 compiler.encode_uchar4(
6442 from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset),
6443 compiler.encode_uchar4(range_type, steps_stack_offset, result_stack_offset));
6444
6445 compiler.add_node(__float_as_int(from_min),
6446 __float_as_int(from_max),
6447 __float_as_int(to_min),
6448 __float_as_int(to_max));
6449 compiler.add_node(__float_as_int(steps));
6450}
6451
6452void MapRangeNode::compile(OSLCompiler &compiler)
6453{
6454 compiler.parameter(this, "range_type");
6455 compiler.add(this, "node_map_range");
6456}
6457
6458/* Vector Map Range Node */
6459
6461{
6462 NodeType *type = NodeType::add("vector_map_range", create, NodeType::SHADER);
6463
6464 static NodeEnum type_enum;
6465 type_enum.insert("linear", NODE_MAP_RANGE_LINEAR);
6466 type_enum.insert("stepped", NODE_MAP_RANGE_STEPPED);
6467 type_enum.insert("smoothstep", NODE_MAP_RANGE_SMOOTHSTEP);
6468 type_enum.insert("smootherstep", NODE_MAP_RANGE_SMOOTHERSTEP);
6469 SOCKET_ENUM(range_type, "Type", type_enum, NODE_MAP_RANGE_LINEAR);
6470
6471 SOCKET_IN_VECTOR(vector, "Vector", zero_float3());
6472 SOCKET_IN_VECTOR(from_min, "From_Min_FLOAT3", zero_float3());
6473 SOCKET_IN_VECTOR(from_max, "From_Max_FLOAT3", one_float3());
6474 SOCKET_IN_VECTOR(to_min, "To_Min_FLOAT3", zero_float3());
6475 SOCKET_IN_VECTOR(to_max, "To_Max_FLOAT3", one_float3());
6476 SOCKET_IN_VECTOR(steps, "Steps_FLOAT3", make_float3(4.0f));
6477 SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
6478
6479 SOCKET_OUT_VECTOR(vector, "Vector");
6480
6481 return type;
6482}
6483
6484VectorMapRangeNode::VectorMapRangeNode() : ShaderNode(get_node_type()) {}
6485
6487
6489{
6490 ShaderInput *vector_in = input("Vector");
6491 ShaderInput *from_min_in = input("From_Min_FLOAT3");
6492 ShaderInput *from_max_in = input("From_Max_FLOAT3");
6493 ShaderInput *to_min_in = input("To_Min_FLOAT3");
6494 ShaderInput *to_max_in = input("To_Max_FLOAT3");
6495 ShaderInput *steps_in = input("Steps_FLOAT3");
6496 ShaderOutput *vector_out = output("Vector");
6497
6498 int value_stack_offset = compiler.stack_assign(vector_in);
6499 int from_min_stack_offset = compiler.stack_assign(from_min_in);
6500 int from_max_stack_offset = compiler.stack_assign(from_max_in);
6501 int to_min_stack_offset = compiler.stack_assign(to_min_in);
6502 int to_max_stack_offset = compiler.stack_assign(to_max_in);
6503 int steps_stack_offset = compiler.stack_assign(steps_in);
6504 int result_stack_offset = compiler.stack_assign(vector_out);
6505
6506 compiler.add_node(
6507 NODE_VECTOR_MAP_RANGE,
6508 value_stack_offset,
6509 compiler.encode_uchar4(
6510 from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset),
6511 compiler.encode_uchar4(steps_stack_offset, use_clamp, range_type, result_stack_offset));
6512}
6513
6515{
6516 compiler.parameter(this, "range_type");
6517 compiler.parameter(this, "use_clamp");
6518 compiler.add(this, "node_vector_map_range");
6519}
6520
6521/* Clamp Node */
6522
6524{
6525 NodeType *type = NodeType::add("clamp", create, NodeType::SHADER);
6526
6527 static NodeEnum type_enum;
6528 type_enum.insert("minmax", NODE_CLAMP_MINMAX);
6529 type_enum.insert("range", NODE_CLAMP_RANGE);
6530 SOCKET_ENUM(clamp_type, "Type", type_enum, NODE_CLAMP_MINMAX);
6531
6532 SOCKET_IN_FLOAT(value, "Value", 1.0f);
6533 SOCKET_IN_FLOAT(min, "Min", 0.0f);
6534 SOCKET_IN_FLOAT(max, "Max", 1.0f);
6535
6536 SOCKET_OUT_FLOAT(result, "Result");
6537
6538 return type;
6539}
6540
6541ClampNode::ClampNode() : ShaderNode(get_node_type()) {}
6542
6544{
6545 if (folder.all_inputs_constant()) {
6546 if (clamp_type == NODE_CLAMP_RANGE && (min > max)) {
6547 folder.make_constant(clamp(value, max, min));
6548 }
6549 else {
6550 folder.make_constant(clamp(value, min, max));
6551 }
6552 }
6553}
6554
6555void ClampNode::compile(SVMCompiler &compiler)
6556{
6557 ShaderInput *value_in = input("Value");
6558 ShaderInput *min_in = input("Min");
6559 ShaderInput *max_in = input("Max");
6560 ShaderOutput *result_out = output("Result");
6561
6562 int value_stack_offset = compiler.stack_assign(value_in);
6563 int min_stack_offset = compiler.stack_assign(min_in);
6564 int max_stack_offset = compiler.stack_assign(max_in);
6565 int result_stack_offset = compiler.stack_assign(result_out);
6566
6567 compiler.add_node(NODE_CLAMP,
6568 value_stack_offset,
6569 compiler.encode_uchar4(min_stack_offset, max_stack_offset, clamp_type),
6570 result_stack_offset);
6571 compiler.add_node(__float_as_int(min), __float_as_int(max));
6572}
6573
6574void ClampNode::compile(OSLCompiler &compiler)
6575{
6576 compiler.parameter(this, "clamp_type");
6577 compiler.add(this, "node_clamp");
6578}
6579
6580/* AOV Output */
6581
6583{
6584 NodeType *type = NodeType::add("aov_output", create, NodeType::SHADER);
6585
6586 SOCKET_IN_COLOR(color, "Color", zero_float3());
6587 SOCKET_IN_FLOAT(value, "Value", 0.0f);
6588
6589 SOCKET_STRING(name, "AOV Name", ustring(""));
6590
6591 return type;
6592}
6593
6594OutputAOVNode::OutputAOVNode() : ShaderNode(get_node_type())
6595{
6596 special_type = SHADER_SPECIAL_TYPE_OUTPUT_AOV;
6597 offset = -1;
6598}
6599
6601{
6602 offset = scene->film->get_aov_offset(scene, name.string(), is_color);
6603 if (offset == -1) {
6604 offset = scene->film->get_aov_offset(scene, name.string(), is_color);
6605 }
6606
6607 if (offset == -1 || is_color) {
6608 input("Value")->disconnect();
6609 }
6610 if (offset == -1 || !is_color) {
6611 input("Color")->disconnect();
6612 }
6613}
6614
6615void OutputAOVNode::compile(SVMCompiler &compiler)
6616{
6617 assert(offset >= 0);
6618
6619 if (is_color) {
6620 compiler.add_node(NODE_AOV_COLOR, compiler.stack_assign(input("Color")), offset);
6621 }
6622 else {
6623 compiler.add_node(NODE_AOV_VALUE, compiler.stack_assign(input("Value")), offset);
6624 }
6625}
6626
6627void OutputAOVNode::compile(OSLCompiler & /*compiler*/)
6628{
6629 /* TODO */
6630}
6631
6632/* Math */
6633
6635{
6636 NodeType *type = NodeType::add("math", create, NodeType::SHADER);
6637
6638 static NodeEnum type_enum;
6639 type_enum.insert("add", NODE_MATH_ADD);
6640 type_enum.insert("subtract", NODE_MATH_SUBTRACT);
6641 type_enum.insert("multiply", NODE_MATH_MULTIPLY);
6642 type_enum.insert("divide", NODE_MATH_DIVIDE);
6643 type_enum.insert("multiply_add", NODE_MATH_MULTIPLY_ADD);
6644 type_enum.insert("sine", NODE_MATH_SINE);
6645 type_enum.insert("cosine", NODE_MATH_COSINE);
6646 type_enum.insert("tangent", NODE_MATH_TANGENT);
6647 type_enum.insert("sinh", NODE_MATH_SINH);
6648 type_enum.insert("cosh", NODE_MATH_COSH);
6649 type_enum.insert("tanh", NODE_MATH_TANH);
6650 type_enum.insert("arcsine", NODE_MATH_ARCSINE);
6651 type_enum.insert("arccosine", NODE_MATH_ARCCOSINE);
6652 type_enum.insert("arctangent", NODE_MATH_ARCTANGENT);
6653 type_enum.insert("power", NODE_MATH_POWER);
6654 type_enum.insert("logarithm", NODE_MATH_LOGARITHM);
6655 type_enum.insert("minimum", NODE_MATH_MINIMUM);
6656 type_enum.insert("maximum", NODE_MATH_MAXIMUM);
6657 type_enum.insert("round", NODE_MATH_ROUND);
6658 type_enum.insert("less_than", NODE_MATH_LESS_THAN);
6659 type_enum.insert("greater_than", NODE_MATH_GREATER_THAN);
6660 type_enum.insert("modulo", NODE_MATH_MODULO);
6661 type_enum.insert("floored_modulo", NODE_MATH_FLOORED_MODULO);
6662 type_enum.insert("absolute", NODE_MATH_ABSOLUTE);
6663 type_enum.insert("arctan2", NODE_MATH_ARCTAN2);
6664 type_enum.insert("floor", NODE_MATH_FLOOR);
6665 type_enum.insert("ceil", NODE_MATH_CEIL);
6666 type_enum.insert("fraction", NODE_MATH_FRACTION);
6667 type_enum.insert("trunc", NODE_MATH_TRUNC);
6668 type_enum.insert("snap", NODE_MATH_SNAP);
6669 type_enum.insert("wrap", NODE_MATH_WRAP);
6670 type_enum.insert("pingpong", NODE_MATH_PINGPONG);
6671 type_enum.insert("sqrt", NODE_MATH_SQRT);
6672 type_enum.insert("inversesqrt", NODE_MATH_INV_SQRT);
6673 type_enum.insert("sign", NODE_MATH_SIGN);
6674 type_enum.insert("exponent", NODE_MATH_EXPONENT);
6675 type_enum.insert("radians", NODE_MATH_RADIANS);
6676 type_enum.insert("degrees", NODE_MATH_DEGREES);
6677 type_enum.insert("smoothmin", NODE_MATH_SMOOTH_MIN);
6678 type_enum.insert("smoothmax", NODE_MATH_SMOOTH_MAX);
6679 type_enum.insert("compare", NODE_MATH_COMPARE);
6680 SOCKET_ENUM(math_type, "Type", type_enum, NODE_MATH_ADD);
6681
6682 SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
6683
6684 SOCKET_IN_FLOAT(value1, "Value1", 0.5f);
6685 SOCKET_IN_FLOAT(value2, "Value2", 0.5f);
6686 SOCKET_IN_FLOAT(value3, "Value3", 0.0f);
6687
6688 SOCKET_OUT_FLOAT(value, "Value");
6689
6690 return type;
6691}
6692
6693MathNode::MathNode() : ShaderNode(get_node_type()) {}
6694
6696{
6697 if (use_clamp) {
6698 ShaderOutput *result_out = output("Value");
6699 if (!result_out->links.empty()) {
6700 ClampNode *clamp_node = graph->create_node<ClampNode>();
6701 clamp_node->set_clamp_type(NODE_CLAMP_MINMAX);
6702 clamp_node->set_min(0.0f);
6703 clamp_node->set_max(1.0f);
6704 graph->add(clamp_node);
6705 graph->relink(result_out, clamp_node->output("Result"));
6706 graph->connect(result_out, clamp_node->input("Value"));
6707 }
6708 }
6709}
6710
6712{
6713 if (folder.all_inputs_constant()) {
6714 folder.make_constant(svm_math(math_type, value1, value2, value3));
6715 }
6716 else {
6717 folder.fold_math(math_type);
6718 }
6719}
6720
6721void MathNode::compile(SVMCompiler &compiler)
6722{
6723 ShaderInput *value1_in = input("Value1");
6724 ShaderInput *value2_in = input("Value2");
6725 ShaderInput *value3_in = input("Value3");
6726 ShaderOutput *value_out = output("Value");
6727
6728 int value1_stack_offset = compiler.stack_assign(value1_in);
6729 int value2_stack_offset = compiler.stack_assign(value2_in);
6730 int value3_stack_offset = compiler.stack_assign(value3_in);
6731 int value_stack_offset = compiler.stack_assign(value_out);
6732
6733 compiler.add_node(
6734 NODE_MATH,
6735 math_type,
6736 compiler.encode_uchar4(value1_stack_offset, value2_stack_offset, value3_stack_offset),
6737 value_stack_offset);
6738}
6739
6740void MathNode::compile(OSLCompiler &compiler)
6741{
6742 compiler.parameter(this, "math_type");
6743 compiler.add(this, "node_math");
6744}
6745
6746/* VectorMath */
6747
6749{
6750 NodeType *type = NodeType::add("vector_math", create, NodeType::SHADER);
6751
6752 static NodeEnum type_enum;
6753 type_enum.insert("add", NODE_VECTOR_MATH_ADD);
6754 type_enum.insert("subtract", NODE_VECTOR_MATH_SUBTRACT);
6755 type_enum.insert("multiply", NODE_VECTOR_MATH_MULTIPLY);
6756 type_enum.insert("divide", NODE_VECTOR_MATH_DIVIDE);
6757
6758 type_enum.insert("cross_product", NODE_VECTOR_MATH_CROSS_PRODUCT);
6759 type_enum.insert("project", NODE_VECTOR_MATH_PROJECT);
6760 type_enum.insert("reflect", NODE_VECTOR_MATH_REFLECT);
6761 type_enum.insert("refract", NODE_VECTOR_MATH_REFRACT);
6762 type_enum.insert("faceforward", NODE_VECTOR_MATH_FACEFORWARD);
6763 type_enum.insert("multiply_add", NODE_VECTOR_MATH_MULTIPLY_ADD);
6764
6765 type_enum.insert("dot_product", NODE_VECTOR_MATH_DOT_PRODUCT);
6766
6767 type_enum.insert("distance", NODE_VECTOR_MATH_DISTANCE);
6768 type_enum.insert("length", NODE_VECTOR_MATH_LENGTH);
6769 type_enum.insert("scale", NODE_VECTOR_MATH_SCALE);
6770 type_enum.insert("normalize", NODE_VECTOR_MATH_NORMALIZE);
6771
6772 type_enum.insert("snap", NODE_VECTOR_MATH_SNAP);
6773 type_enum.insert("floor", NODE_VECTOR_MATH_FLOOR);
6774 type_enum.insert("ceil", NODE_VECTOR_MATH_CEIL);
6775 type_enum.insert("modulo", NODE_VECTOR_MATH_MODULO);
6776 type_enum.insert("wrap", NODE_VECTOR_MATH_WRAP);
6777 type_enum.insert("fraction", NODE_VECTOR_MATH_FRACTION);
6778 type_enum.insert("absolute", NODE_VECTOR_MATH_ABSOLUTE);
6779 type_enum.insert("minimum", NODE_VECTOR_MATH_MINIMUM);
6780 type_enum.insert("maximum", NODE_VECTOR_MATH_MAXIMUM);
6781
6782 type_enum.insert("sine", NODE_VECTOR_MATH_SINE);
6783 type_enum.insert("cosine", NODE_VECTOR_MATH_COSINE);
6784 type_enum.insert("tangent", NODE_VECTOR_MATH_TANGENT);
6785 SOCKET_ENUM(math_type, "Type", type_enum, NODE_VECTOR_MATH_ADD);
6786
6787 SOCKET_IN_VECTOR(vector1, "Vector1", zero_float3());
6788 SOCKET_IN_VECTOR(vector2, "Vector2", zero_float3());
6789 SOCKET_IN_VECTOR(vector3, "Vector3", zero_float3());
6790 SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
6791
6792 SOCKET_OUT_FLOAT(value, "Value");
6793 SOCKET_OUT_VECTOR(vector, "Vector");
6794
6795 return type;
6796}
6797
6798VectorMathNode::VectorMathNode() : ShaderNode(get_node_type()) {}
6799
6801{
6802 float value = 0.0f;
6804
6805 if (folder.all_inputs_constant()) {
6806 svm_vector_math(&value, &vector, math_type, vector1, vector2, vector3, scale);
6807 if (folder.output == output("Value")) {
6808 folder.make_constant(value);
6809 }
6810 else if (folder.output == output("Vector")) {
6811 folder.make_constant(vector);
6812 }
6813 }
6814 else {
6815 folder.fold_vector_math(math_type);
6816 }
6817}
6818
6820{
6821 ShaderInput *vector1_in = input("Vector1");
6822 ShaderInput *vector2_in = input("Vector2");
6823 ShaderInput *param1_in = input("Scale");
6824 ShaderOutput *value_out = output("Value");
6825 ShaderOutput *vector_out = output("Vector");
6826
6827 int vector1_stack_offset = compiler.stack_assign(vector1_in);
6828 int vector2_stack_offset = compiler.stack_assign(vector2_in);
6829 int param1_stack_offset = compiler.stack_assign(param1_in);
6830 int value_stack_offset = compiler.stack_assign_if_linked(value_out);
6831 int vector_stack_offset = compiler.stack_assign_if_linked(vector_out);
6832
6833 /* 3 Vector Operators */
6834 if (math_type == NODE_VECTOR_MATH_WRAP || math_type == NODE_VECTOR_MATH_FACEFORWARD ||
6835 math_type == NODE_VECTOR_MATH_MULTIPLY_ADD)
6836 {
6837 ShaderInput *vector3_in = input("Vector3");
6838 int vector3_stack_offset = compiler.stack_assign(vector3_in);
6839 compiler.add_node(
6840 NODE_VECTOR_MATH,
6841 math_type,
6842 compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, param1_stack_offset),
6843 compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
6844 compiler.add_node(vector3_stack_offset);
6845 }
6846 else {
6847 compiler.add_node(
6848 NODE_VECTOR_MATH,
6849 math_type,
6850 compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, param1_stack_offset),
6851 compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
6852 }
6853}
6854
6856{
6857 compiler.parameter(this, "math_type");
6858 compiler.add(this, "node_vector_math");
6859}
6860
6861/* Vector Rotate */
6862
6864{
6865 NodeType *type = NodeType::add("vector_rotate", create, NodeType::SHADER);
6866
6867 static NodeEnum type_enum;
6868 type_enum.insert("axis", NODE_VECTOR_ROTATE_TYPE_AXIS);
6869 type_enum.insert("x_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_X);
6870 type_enum.insert("y_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Y);
6871 type_enum.insert("z_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Z);
6872 type_enum.insert("euler_xyz", NODE_VECTOR_ROTATE_TYPE_EULER_XYZ);
6873 SOCKET_ENUM(rotate_type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS);
6874
6875 SOCKET_BOOLEAN(invert, "Invert", false);
6876
6877 SOCKET_IN_VECTOR(vector, "Vector", zero_float3());
6878 SOCKET_IN_POINT(rotation, "Rotation", zero_float3());
6879 SOCKET_IN_POINT(center, "Center", zero_float3());
6880 SOCKET_IN_VECTOR(axis, "Axis", make_float3(0.0f, 0.0f, 1.0f));
6881 SOCKET_IN_FLOAT(angle, "Angle", 0.0f);
6882 SOCKET_OUT_VECTOR(vector, "Vector");
6883
6884 return type;
6885}
6886
6887VectorRotateNode::VectorRotateNode() : ShaderNode(get_node_type()) {}
6888
6890{
6891 ShaderInput *vector_in = input("Vector");
6892 ShaderInput *rotation_in = input("Rotation");
6893 ShaderInput *center_in = input("Center");
6894 ShaderInput *axis_in = input("Axis");
6895 ShaderInput *angle_in = input("Angle");
6896 ShaderOutput *vector_out = output("Vector");
6897
6898 compiler.add_node(NODE_VECTOR_ROTATE,
6899 compiler.encode_uchar4(rotate_type,
6900 compiler.stack_assign(vector_in),
6901 compiler.stack_assign(rotation_in),
6902 invert),
6903 compiler.encode_uchar4(compiler.stack_assign(center_in),
6904 compiler.stack_assign(axis_in),
6905 compiler.stack_assign(angle_in)),
6906 compiler.stack_assign(vector_out));
6907}
6908
6910{
6911 compiler.parameter(this, "rotate_type");
6912 compiler.parameter(this, "invert");
6913 compiler.add(this, "node_vector_rotate");
6914}
6915
6916/* VectorTransform */
6917
6919{
6920 NodeType *type = NodeType::add("vector_transform", create, NodeType::SHADER);
6921
6922 static NodeEnum type_enum;
6923 type_enum.insert("vector", NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
6924 type_enum.insert("point", NODE_VECTOR_TRANSFORM_TYPE_POINT);
6925 type_enum.insert("normal", NODE_VECTOR_TRANSFORM_TYPE_NORMAL);
6926 SOCKET_ENUM(transform_type, "Type", type_enum, NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
6927
6928 static NodeEnum space_enum;
6932 SOCKET_ENUM(convert_from, "Convert From", space_enum, NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD);
6933 SOCKET_ENUM(convert_to, "Convert To", space_enum, NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT);
6934
6935 SOCKET_IN_VECTOR(vector, "Vector", zero_float3());
6936 SOCKET_OUT_VECTOR(vector, "Vector");
6937
6938 return type;
6939}
6940
6941VectorTransformNode::VectorTransformNode() : ShaderNode(get_node_type()) {}
6942
6944{
6945 ShaderInput *vector_in = input("Vector");
6946 ShaderOutput *vector_out = output("Vector");
6947
6948 compiler.add_node(
6949 NODE_VECTOR_TRANSFORM,
6950 compiler.encode_uchar4(transform_type, convert_from, convert_to),
6951 compiler.encode_uchar4(compiler.stack_assign(vector_in), compiler.stack_assign(vector_out)));
6952}
6953
6955{
6956 compiler.parameter(this, "transform_type");
6957 compiler.parameter(this, "convert_from");
6958 compiler.parameter(this, "convert_to");
6959 compiler.add(this, "node_vector_transform");
6960}
6961
6962/* BumpNode */
6963
6965{
6966 NodeType *type = NodeType::add("bump", create, NodeType::SHADER);
6967
6968 SOCKET_BOOLEAN(invert, "Invert", false);
6969 SOCKET_BOOLEAN(use_object_space, "UseObjectSpace", false);
6970
6971 /* this input is used by the user, but after graph transform it is no longer
6972 * used and moved to sampler center/x/y instead */
6973 SOCKET_IN_FLOAT(height, "Height", 1.0f);
6974
6975 SOCKET_IN_FLOAT(sample_center, "SampleCenter", 0.0f);
6976 SOCKET_IN_FLOAT(sample_x, "SampleX", 0.0f);
6977 SOCKET_IN_FLOAT(sample_y, "SampleY", 0.0f);
6979 SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
6980 SOCKET_IN_FLOAT(distance, "Distance", 0.1f);
6981
6982 SOCKET_OUT_NORMAL(normal, "Normal");
6983
6984 return type;
6985}
6986
6987BumpNode::BumpNode() : ShaderNode(get_node_type())
6988{
6989 special_type = SHADER_SPECIAL_TYPE_BUMP;
6990}
6991
6992void BumpNode::compile(SVMCompiler &compiler)
6993{
6994 ShaderInput *center_in = input("SampleCenter");
6995 ShaderInput *dx_in = input("SampleX");
6996 ShaderInput *dy_in = input("SampleY");
6997 ShaderInput *normal_in = input("Normal");
6998 ShaderInput *strength_in = input("Strength");
6999 ShaderInput *distance_in = input("Distance");
7000 ShaderOutput *normal_out = output("Normal");
7001
7002 /* pack all parameters in the node */
7003 compiler.add_node(
7004 NODE_SET_BUMP,
7005 compiler.encode_uchar4(compiler.stack_assign_if_linked(normal_in),
7006 compiler.stack_assign(distance_in),
7007 invert,
7008 use_object_space),
7009 compiler.encode_uchar4(compiler.stack_assign(center_in),
7010 compiler.stack_assign(dx_in),
7011 compiler.stack_assign(dy_in),
7012 compiler.stack_assign(strength_in)),
7013 compiler.encode_uchar4(compiler.stack_assign(normal_out), compiler.get_bump_state_offset()));
7014}
7015
7016void BumpNode::compile(OSLCompiler &compiler)
7017{
7018 compiler.parameter(this, "invert");
7019 compiler.parameter(this, "use_object_space");
7020 compiler.add(this, "node_bump");
7021}
7022
7024{
7025 ShaderInput *height_in = input("Height");
7026 ShaderInput *normal_in = input("Normal");
7027
7028 if (height_in->link == NULL) {
7029 if (normal_in->link == NULL) {
7030 GeometryNode *geom = folder.graph->create_node<GeometryNode>();
7031 folder.graph->add(geom);
7032 folder.bypass(geom->output("Normal"));
7033 }
7034 else {
7035 folder.bypass(normal_in->link);
7036 }
7037 }
7038
7039 /* TODO(sergey): Ignore bump with zero strength. */
7040}
7041
7042/* Curves node */
7043
7044CurvesNode::CurvesNode(const NodeType *node_type) : ShaderNode(node_type) {}
7045
7047{
7048 ShaderInput *fac_in = input("Fac");
7049
7050 /* evaluate fully constant node */
7051 if (folder.all_inputs_constant()) {
7052 if (curves.size() == 0) {
7053 return;
7054 }
7055
7056 float3 pos = (value - make_float3(min_x, min_x, min_x)) / (max_x - min_x);
7057 float3 result;
7058
7059 result[0] = rgb_ramp_lookup(curves.data(), pos[0], true, extrapolate, curves.size()).x;
7060 result[1] = rgb_ramp_lookup(curves.data(), pos[1], true, extrapolate, curves.size()).y;
7061 result[2] = rgb_ramp_lookup(curves.data(), pos[2], true, extrapolate, curves.size()).z;
7062
7063 folder.make_constant(interp(value, result, fac));
7064 }
7065 /* remove no-op node */
7066 else if (!fac_in->link && fac == 0.0f) {
7067 /* link is not null because otherwise all inputs are constant */
7068 folder.bypass(value_in->link);
7069 }
7070}
7071
7073 int type,
7074 ShaderInput *value_in,
7075 ShaderOutput *value_out)
7076{
7077 if (curves.size() == 0) {
7078 return;
7079 }
7080
7081 ShaderInput *fac_in = input("Fac");
7082
7083 compiler.add_node(ShaderNodeType(type),
7084 compiler.encode_uchar4(compiler.stack_assign(fac_in),
7085 compiler.stack_assign(value_in),
7086 compiler.stack_assign(value_out),
7087 extrapolate),
7088 __float_as_int(min_x),
7089 __float_as_int(max_x));
7090
7091 compiler.add_node(curves.size());
7092 for (int i = 0; i < curves.size(); i++) {
7093 compiler.add_node(float3_to_float4(curves[i]));
7094 }
7095}
7096
7097void CurvesNode::compile(OSLCompiler &compiler, const char *name)
7098{
7099 if (curves.size() == 0) {
7100 return;
7101 }
7102
7103 compiler.parameter_color_array("ramp", curves);
7104 compiler.parameter(this, "min_x");
7105 compiler.parameter(this, "max_x");
7106 compiler.parameter(this, "extrapolate");
7107 compiler.add(this, name);
7108}
7109
7110void CurvesNode::compile(SVMCompiler & /*compiler*/)
7111{
7112 assert(0);
7113}
7114
7115void CurvesNode::compile(OSLCompiler & /*compiler*/)
7116{
7117 assert(0);
7118}
7119
7120/* RGBCurvesNode */
7121
7123{
7124 NodeType *type = NodeType::add("rgb_curves", create, NodeType::SHADER);
7125
7126 SOCKET_COLOR_ARRAY(curves, "Curves", array<float3>());
7127 SOCKET_FLOAT(min_x, "Min X", 0.0f);
7128 SOCKET_FLOAT(max_x, "Max X", 1.0f);
7129 SOCKET_BOOLEAN(extrapolate, "Extrapolate", true);
7130
7131 SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
7132 SOCKET_IN_COLOR(value, "Color", zero_float3());
7133
7134 SOCKET_OUT_COLOR(value, "Color");
7135
7136 return type;
7137}
7138
7139RGBCurvesNode::RGBCurvesNode() : CurvesNode(get_node_type()) {}
7140
7142{
7143 CurvesNode::constant_fold(folder, input("Color"));
7144}
7145
7146void RGBCurvesNode::compile(SVMCompiler &compiler)
7147{
7148 CurvesNode::compile(compiler, NODE_CURVES, input("Color"), output("Color"));
7149}
7150
7151void RGBCurvesNode::compile(OSLCompiler &compiler)
7152{
7153 CurvesNode::compile(compiler, "node_rgb_curves");
7154}
7155
7156/* VectorCurvesNode */
7157
7159{
7160 NodeType *type = NodeType::add("vector_curves", create, NodeType::SHADER);
7161
7162 SOCKET_VECTOR_ARRAY(curves, "Curves", array<float3>());
7163 SOCKET_FLOAT(min_x, "Min X", 0.0f);
7164 SOCKET_FLOAT(max_x, "Max X", 1.0f);
7165 SOCKET_BOOLEAN(extrapolate, "Extrapolate", true);
7166
7167 SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
7168 SOCKET_IN_VECTOR(value, "Vector", zero_float3());
7169
7170 SOCKET_OUT_VECTOR(value, "Vector");
7171
7172 return type;
7173}
7174
7175VectorCurvesNode::VectorCurvesNode() : CurvesNode(get_node_type()) {}
7176
7178{
7179 CurvesNode::constant_fold(folder, input("Vector"));
7180}
7181
7183{
7184 CurvesNode::compile(compiler, NODE_CURVES, input("Vector"), output("Vector"));
7185}
7186
7188{
7189 CurvesNode::compile(compiler, "node_vector_curves");
7190}
7191
7192/* FloatCurveNode */
7193
7195{
7196 NodeType *type = NodeType::add("float_curve", create, NodeType::SHADER);
7197
7198 SOCKET_FLOAT_ARRAY(curve, "Curve", array<float>());
7199 SOCKET_FLOAT(min_x, "Min X", 0.0f);
7200 SOCKET_FLOAT(max_x, "Max X", 1.0f);
7201 SOCKET_BOOLEAN(extrapolate, "Extrapolate", true);
7202
7203 SOCKET_IN_FLOAT(fac, "Factor", 0.0f);
7204 SOCKET_IN_FLOAT(value, "Value", 0.0f);
7205
7206 SOCKET_OUT_FLOAT(value, "Value");
7207
7208 return type;
7209}
7210
7211FloatCurveNode::FloatCurveNode() : ShaderNode(get_node_type()) {}
7212
7214{
7215 ShaderInput *value_in = input("Value");
7216 ShaderInput *fac_in = input("Factor");
7217
7218 /* evaluate fully constant node */
7219 if (folder.all_inputs_constant()) {
7220 if (curve.size() == 0) {
7221 return;
7222 }
7223
7224 float pos = (value - min_x) / (max_x - min_x);
7225 float result = float_ramp_lookup(curve.data(), pos, true, extrapolate, curve.size());
7226
7227 folder.make_constant(value + fac * (result - value));
7228 }
7229 /* remove no-op node */
7230 else if (!fac_in->link && fac == 0.0f) {
7231 /* link is not null because otherwise all inputs are constant */
7232 folder.bypass(value_in->link);
7233 }
7234}
7235
7237{
7238 if (curve.size() == 0) {
7239 return;
7240 }
7241
7242 ShaderInput *value_in = input("Value");
7243 ShaderInput *fac_in = input("Factor");
7244 ShaderOutput *value_out = output("Value");
7245
7246 compiler.add_node(NODE_FLOAT_CURVE,
7247 compiler.encode_uchar4(compiler.stack_assign(fac_in),
7248 compiler.stack_assign(value_in),
7249 compiler.stack_assign(value_out),
7250 extrapolate),
7251 __float_as_int(min_x),
7252 __float_as_int(max_x));
7253
7254 compiler.add_node(curve.size());
7255 for (int i = 0; i < curve.size(); i++) {
7256 compiler.add_node(make_float4(curve[i]));
7257 }
7258}
7259
7261{
7262 if (curve.size() == 0) {
7263 return;
7264 }
7265
7266 compiler.parameter_array("ramp", curve.data(), curve.size());
7267 compiler.parameter(this, "min_x");
7268 compiler.parameter(this, "max_x");
7269 compiler.parameter(this, "extrapolate");
7270 compiler.add(this, "node_float_curve");
7271}
7272
7273/* RGBRampNode */
7274
7276{
7277 NodeType *type = NodeType::add("rgb_ramp", create, NodeType::SHADER);
7278
7279 SOCKET_COLOR_ARRAY(ramp, "Ramp", array<float3>());
7280 SOCKET_FLOAT_ARRAY(ramp_alpha, "Ramp Alpha", array<float>());
7281 SOCKET_BOOLEAN(interpolate, "Interpolate", true);
7282
7283 SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
7284
7285 SOCKET_OUT_COLOR(color, "Color");
7286 SOCKET_OUT_FLOAT(alpha, "Alpha");
7287
7288 return type;
7289}
7290
7291RGBRampNode::RGBRampNode() : ShaderNode(get_node_type()) {}
7292
7294{
7295 if (ramp.size() == 0 || ramp.size() != ramp_alpha.size()) {
7296 return;
7297 }
7298
7299 if (folder.all_inputs_constant()) {
7300 float f = clamp(fac, 0.0f, 1.0f) * (ramp.size() - 1);
7301
7302 /* clamp int as well in case of NaN */
7303 int i = clamp((int)f, 0, ramp.size() - 1);
7304 float t = f - (float)i;
7305
7306 bool use_lerp = interpolate && t > 0.0f;
7307
7308 if (folder.output == output("Color")) {
7309 float3 color = rgb_ramp_lookup(ramp.data(), fac, use_lerp, false, ramp.size());
7310 folder.make_constant(color);
7311 }
7312 else if (folder.output == output("Alpha")) {
7313 float alpha = float_ramp_lookup(ramp_alpha.data(), fac, use_lerp, false, ramp_alpha.size());
7314 folder.make_constant(alpha);
7315 }
7316 }
7317}
7318
7319void RGBRampNode::compile(SVMCompiler &compiler)
7320{
7321 if (ramp.size() == 0 || ramp.size() != ramp_alpha.size()) {
7322 return;
7323 }
7324
7325 ShaderInput *fac_in = input("Fac");
7326 ShaderOutput *color_out = output("Color");
7327 ShaderOutput *alpha_out = output("Alpha");
7328
7329 compiler.add_node(NODE_RGB_RAMP,
7330 compiler.encode_uchar4(compiler.stack_assign(fac_in),
7331 compiler.stack_assign_if_linked(color_out),
7332 compiler.stack_assign_if_linked(alpha_out)),
7333 interpolate);
7334
7335 compiler.add_node(ramp.size());
7336 for (int i = 0; i < ramp.size(); i++) {
7337 compiler.add_node(make_float4(ramp[i].x, ramp[i].y, ramp[i].z, ramp_alpha[i]));
7338 }
7339}
7340
7341void RGBRampNode::compile(OSLCompiler &compiler)
7342{
7343 if (ramp.size() == 0 || ramp.size() != ramp_alpha.size()) {
7344 return;
7345 }
7346
7347 compiler.parameter_color_array("ramp_color", ramp);
7348 compiler.parameter_array("ramp_alpha", ramp_alpha.data(), ramp_alpha.size());
7349 compiler.parameter(this, "interpolate");
7350
7351 compiler.add(this, "node_rgb_ramp");
7352}
7353
7354/* Set Normal Node */
7355
7357{
7358 NodeType *type = NodeType::add("set_normal", create, NodeType::SHADER);
7359
7360 SOCKET_IN_VECTOR(direction, "Direction", zero_float3());
7361 SOCKET_OUT_NORMAL(normal, "Normal");
7362
7363 return type;
7364}
7365
7366SetNormalNode::SetNormalNode() : ShaderNode(get_node_type()) {}
7367
7368void SetNormalNode::compile(SVMCompiler &compiler)
7369{
7370 ShaderInput *direction_in = input("Direction");
7371 ShaderOutput *normal_out = output("Normal");
7372
7373 compiler.add_node(NODE_CLOSURE_SET_NORMAL,
7374 compiler.stack_assign(direction_in),
7375 compiler.stack_assign(normal_out));
7376}
7377
7378void SetNormalNode::compile(OSLCompiler &compiler)
7379{
7380 compiler.add(this, "node_set_normal");
7381}
7382
7383/* OSLNode */
7384
7385OSLNode::OSLNode() : ShaderNode(new NodeType(NodeType::SHADER))
7386{
7387 special_type = SHADER_SPECIAL_TYPE_OSL;
7388 has_emission = false;
7389}
7390
7392{
7393 delete type;
7394}
7395
7397{
7398 return OSLNode::create(graph, this->inputs.size(), this);
7399}
7400
7401OSLNode *OSLNode::create(ShaderGraph *graph, size_t num_inputs, const OSLNode *from)
7402{
7403 /* allocate space for the node itself and parameters, aligned to 16 bytes
7404 * assuming that's the most parameter types need */
7405 size_t node_size = align_up(sizeof(OSLNode), 16);
7406 size_t inputs_size = align_up(SocketType::max_size(), 16) * num_inputs;
7407
7408 char *node_memory = (char *)operator new(node_size + inputs_size);
7409 memset(node_memory, 0, node_size + inputs_size);
7410
7411 if (!from) {
7412 OSLNode *node = new (node_memory) OSLNode();
7413 node->set_owner(graph);
7414 return node;
7415 }
7416 else {
7417 /* copy input default values and node type for cloning */
7418 memcpy(node_memory + node_size, (char *)from + node_size, inputs_size);
7419
7420 OSLNode *node = new (node_memory) OSLNode(*from);
7421 node->type = new NodeType(*(from->type));
7422 node->set_owner(from->owner);
7423 return node;
7424 }
7425}
7426
7428{
7429 /* pointer to default value storage, which is the same as our actual value */
7430 size_t num_inputs = type->inputs.size();
7431 size_t inputs_size = align_up(SocketType::max_size(), 16) * num_inputs;
7432 return (char *)this + align_up(sizeof(OSLNode), 16) + inputs_size;
7433}
7434
7435void OSLNode::add_input(ustring name, SocketType::Type socket_type, const int flags)
7436{
7437 char *memory = input_default_value();
7438 size_t offset = memory - (char *)this;
7439 const_cast<NodeType *>(type)->register_input(
7440 name, name, socket_type, offset, memory, NULL, NULL, flags | SocketType::LINKABLE);
7441}
7442
7443void OSLNode::add_output(ustring name, SocketType::Type socket_type)
7444{
7445 const_cast<NodeType *>(type)->register_output(name, name, socket_type);
7446}
7447
7449{
7450 /* doesn't work for SVM, obviously ... */
7451}
7452
7453void OSLNode::compile(OSLCompiler &compiler)
7454{
7455 if (!filepath.empty()) {
7456 compiler.add(this, filepath.c_str(), true);
7457 }
7458 else {
7459 compiler.add(this, bytecode_hash.c_str(), false);
7460 }
7461}
7462
7463/* Normal Map */
7464
7466{
7467 NodeType *type = NodeType::add("normal_map", create, NodeType::SHADER);
7468
7469 static NodeEnum space_enum;
7470 space_enum.insert("tangent", NODE_NORMAL_MAP_TANGENT);
7471 space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
7472 space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
7473 space_enum.insert("blender_object", NODE_NORMAL_MAP_BLENDER_OBJECT);
7474 space_enum.insert("blender_world", NODE_NORMAL_MAP_BLENDER_WORLD);
7475 SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_TANGENT);
7476
7477 SOCKET_STRING(attribute, "Attribute", ustring());
7478
7479 SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
7480 SOCKET_IN_COLOR(color, "Color", make_float3(0.5f, 0.5f, 1.0f));
7481
7482 SOCKET_OUT_NORMAL(normal, "Normal");
7483
7484 return type;
7485}
7486
7487NormalMapNode::NormalMapNode() : ShaderNode(get_node_type()) {}
7488
7490{
7491 if (shader->has_surface_link() && space == NODE_NORMAL_MAP_TANGENT) {
7492 if (attribute.empty()) {
7493 attributes->add(ATTR_STD_UV_TANGENT);
7494 attributes->add(ATTR_STD_UV_TANGENT_SIGN);
7495 }
7496 else {
7497 attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
7498 attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
7499 }
7500 }
7501
7502 ShaderNode::attributes(shader, attributes);
7503}
7504
7505void NormalMapNode::compile(SVMCompiler &compiler)
7506{
7507 ShaderInput *color_in = input("Color");
7508 ShaderInput *strength_in = input("Strength");
7509 ShaderOutput *normal_out = output("Normal");
7510 int attr = 0, attr_sign = 0;
7511
7512 if (space == NODE_NORMAL_MAP_TANGENT) {
7513 if (attribute.empty()) {
7514 attr = compiler.attribute(ATTR_STD_UV_TANGENT);
7515 attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN);
7516 }
7517 else {
7518 attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
7519 attr_sign = compiler.attribute(
7520 ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
7521 }
7522 }
7523
7524 compiler.add_node(NODE_NORMAL_MAP,
7525 compiler.encode_uchar4(compiler.stack_assign(color_in),
7526 compiler.stack_assign(strength_in),
7527 compiler.stack_assign(normal_out),
7528 space),
7529 attr,
7530 attr_sign);
7531}
7532
7533void NormalMapNode::compile(OSLCompiler &compiler)
7534{
7535 if (space == NODE_NORMAL_MAP_TANGENT) {
7536 if (attribute.empty()) {
7537 compiler.parameter("attr_name", ustring("geom:tangent"));
7538 compiler.parameter("attr_sign_name", ustring("geom:tangent_sign"));
7539 }
7540 else {
7541 compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
7542 compiler.parameter("attr_sign_name",
7543 ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
7544 }
7545 }
7546
7547 compiler.parameter(this, "space");
7548 compiler.add(this, "node_normal_map");
7549}
7550
7551/* Tangent */
7552
7554{
7555 NodeType *type = NodeType::add("tangent", create, NodeType::SHADER);
7556
7557 static NodeEnum direction_type_enum;
7558 direction_type_enum.insert("radial", NODE_TANGENT_RADIAL);
7559 direction_type_enum.insert("uv_map", NODE_TANGENT_UVMAP);
7560 SOCKET_ENUM(direction_type, "Direction Type", direction_type_enum, NODE_TANGENT_RADIAL);
7561
7562 static NodeEnum axis_enum;
7563 axis_enum.insert("x", NODE_TANGENT_AXIS_X);
7564 axis_enum.insert("y", NODE_TANGENT_AXIS_Y);
7565 axis_enum.insert("z", NODE_TANGENT_AXIS_Z);
7566 SOCKET_ENUM(axis, "Axis", axis_enum, NODE_TANGENT_AXIS_X);
7567
7568 SOCKET_STRING(attribute, "Attribute", ustring());
7569
7570 SOCKET_OUT_NORMAL(tangent, "Tangent");
7571
7572 return type;
7573}
7574
7575TangentNode::TangentNode() : ShaderNode(get_node_type()) {}
7576
7578{
7579 if (shader->has_surface_link()) {
7580 if (direction_type == NODE_TANGENT_UVMAP) {
7581 if (attribute.empty()) {
7582 attributes->add(ATTR_STD_UV_TANGENT);
7583 }
7584 else {
7585 attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
7586 }
7587 }
7588 else {
7589 attributes->add(ATTR_STD_GENERATED);
7590 }
7591 }
7592
7593 ShaderNode::attributes(shader, attributes);
7594}
7595
7596void TangentNode::compile(SVMCompiler &compiler)
7597{
7598 ShaderOutput *tangent_out = output("Tangent");
7599 int attr;
7600
7601 if (direction_type == NODE_TANGENT_UVMAP) {
7602 if (attribute.empty()) {
7603 attr = compiler.attribute(ATTR_STD_UV_TANGENT);
7604 }
7605 else {
7606 attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
7607 }
7608 }
7609 else {
7610 attr = compiler.attribute(ATTR_STD_GENERATED);
7611 }
7612
7613 compiler.add_node(
7614 NODE_TANGENT,
7615 compiler.encode_uchar4(compiler.stack_assign(tangent_out), direction_type, axis),
7616 attr);
7617}
7618
7619void TangentNode::compile(OSLCompiler &compiler)
7620{
7621 if (direction_type == NODE_TANGENT_UVMAP) {
7622 if (attribute.empty()) {
7623 compiler.parameter("attr_name", ustring("geom:tangent"));
7624 }
7625 else {
7626 compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
7627 }
7628 }
7629
7630 compiler.parameter(this, "direction_type");
7631 compiler.parameter(this, "axis");
7632 compiler.add(this, "node_tangent");
7633}
7634
7635/* Bevel */
7636
7638{
7639 NodeType *type = NodeType::add("bevel", create, NodeType::SHADER);
7640
7641 SOCKET_INT(samples, "Samples", 4);
7642
7643 SOCKET_IN_FLOAT(radius, "Radius", 0.05f);
7645
7646 SOCKET_OUT_NORMAL(bevel, "Normal");
7647
7648 return type;
7649}
7650
7651BevelNode::BevelNode() : ShaderNode(get_node_type()) {}
7652
7653void BevelNode::compile(SVMCompiler &compiler)
7654{
7655 ShaderInput *radius_in = input("Radius");
7656 ShaderInput *normal_in = input("Normal");
7657 ShaderOutput *normal_out = output("Normal");
7658
7659 compiler.add_node(NODE_BEVEL,
7660 compiler.encode_uchar4(samples,
7661 compiler.stack_assign(radius_in),
7662 compiler.stack_assign_if_linked(normal_in),
7663 compiler.stack_assign(normal_out)));
7664}
7665
7666void BevelNode::compile(OSLCompiler &compiler)
7667{
7668 compiler.parameter(this, "samples");
7669 compiler.add(this, "node_bevel");
7670}
7671
7672/* Displacement */
7673
7675{
7676 NodeType *type = NodeType::add("displacement", create, NodeType::SHADER);
7677
7678 static NodeEnum space_enum;
7679 space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
7680 space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
7681
7682 SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_OBJECT);
7683
7684 SOCKET_IN_FLOAT(height, "Height", 0.0f);
7685 SOCKET_IN_FLOAT(midlevel, "Midlevel", 0.5f);
7686 SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
7688
7689 SOCKET_OUT_VECTOR(displacement, "Displacement");
7690
7691 return type;
7692}
7693
7694DisplacementNode::DisplacementNode() : ShaderNode(get_node_type()) {}
7695
7697{
7698 if (folder.all_inputs_constant()) {
7699 if ((height - midlevel == 0.0f) || (scale == 0.0f)) {
7700 folder.make_zero();
7701 }
7702 }
7703}
7704
7706{
7707 ShaderInput *height_in = input("Height");
7708 ShaderInput *midlevel_in = input("Midlevel");
7709 ShaderInput *scale_in = input("Scale");
7710 ShaderInput *normal_in = input("Normal");
7711 ShaderOutput *displacement_out = output("Displacement");
7712
7713 compiler.add_node(NODE_DISPLACEMENT,
7714 compiler.encode_uchar4(compiler.stack_assign(height_in),
7715 compiler.stack_assign(midlevel_in),
7716 compiler.stack_assign(scale_in),
7717 compiler.stack_assign_if_linked(normal_in)),
7718 compiler.stack_assign(displacement_out),
7719 space);
7720}
7721
7723{
7724 compiler.parameter(this, "space");
7725 compiler.add(this, "node_displacement");
7726}
7727
7728/* Vector Displacement */
7729
7731{
7732 NodeType *type = NodeType::add("vector_displacement", create, NodeType::SHADER);
7733
7734 static NodeEnum space_enum;
7735 space_enum.insert("tangent", NODE_NORMAL_MAP_TANGENT);
7736 space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
7737 space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
7738
7739 SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_TANGENT);
7740 SOCKET_STRING(attribute, "Attribute", ustring());
7741
7742 SOCKET_IN_COLOR(vector, "Vector", zero_float3());
7743 SOCKET_IN_FLOAT(midlevel, "Midlevel", 0.0f);
7744 SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
7745
7746 SOCKET_OUT_VECTOR(displacement, "Displacement");
7747
7748 return type;
7749}
7750
7751VectorDisplacementNode::VectorDisplacementNode() : ShaderNode(get_node_type()) {}
7752
7754{
7755 if (folder.all_inputs_constant()) {
7756 if ((vector == zero_float3() && midlevel == 0.0f) || (scale == 0.0f)) {
7757 folder.make_zero();
7758 }
7759 }
7760}
7761
7763{
7764 if (shader->has_surface_link() && space == NODE_NORMAL_MAP_TANGENT) {
7765 if (attribute.empty()) {
7766 attributes->add(ATTR_STD_UV_TANGENT);
7767 attributes->add(ATTR_STD_UV_TANGENT_SIGN);
7768 }
7769 else {
7770 attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
7771 attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
7772 }
7773 }
7774
7775 ShaderNode::attributes(shader, attributes);
7776}
7777
7779{
7780 ShaderInput *vector_in = input("Vector");
7781 ShaderInput *midlevel_in = input("Midlevel");
7782 ShaderInput *scale_in = input("Scale");
7783 ShaderOutput *displacement_out = output("Displacement");
7784 int attr = 0, attr_sign = 0;
7785
7786 if (space == NODE_NORMAL_MAP_TANGENT) {
7787 if (attribute.empty()) {
7788 attr = compiler.attribute(ATTR_STD_UV_TANGENT);
7789 attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN);
7790 }
7791 else {
7792 attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
7793 attr_sign = compiler.attribute(
7794 ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
7795 }
7796 }
7797
7798 compiler.add_node(NODE_VECTOR_DISPLACEMENT,
7799 compiler.encode_uchar4(compiler.stack_assign(vector_in),
7800 compiler.stack_assign(midlevel_in),
7801 compiler.stack_assign(scale_in),
7802 compiler.stack_assign(displacement_out)),
7803 attr,
7804 attr_sign);
7805
7806 compiler.add_node(space);
7807}
7808
7810{
7811 if (space == NODE_NORMAL_MAP_TANGENT) {
7812 if (attribute.empty()) {
7813 compiler.parameter("attr_name", ustring("geom:tangent"));
7814 compiler.parameter("attr_sign_name", ustring("geom:tangent_sign"));
7815 }
7816 else {
7817 compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
7818 compiler.parameter("attr_sign_name",
7819 ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
7820 }
7821 }
7822
7823 compiler.parameter(this, "space");
7824 compiler.add(this, "node_vector_displacement");
7825}
7826
MINLINE float signf(float f)
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
void hsv_to_rgb(float h, float s, float v, float *r_r, float *r_g, float *r_b)
Definition math_color.cc:21
unsigned int uint
#define saturate(a)
@ NODE_VECTOR_MATH_NORMALIZE
@ NODE_VECTOR_MATH_LENGTH
@ NODE_VECTOR_MATH_CROSS_PRODUCT
@ NODE_VECTOR_MATH_CEIL
@ NODE_VECTOR_MATH_MODULO
@ NODE_VECTOR_MATH_ADD
@ NODE_VECTOR_MATH_COSINE
@ NODE_VECTOR_MATH_REFLECT
@ NODE_VECTOR_MATH_WRAP
@ NODE_VECTOR_MATH_REFRACT
@ NODE_VECTOR_MATH_DOT_PRODUCT
@ NODE_VECTOR_MATH_ABSOLUTE
@ NODE_VECTOR_MATH_DIVIDE
@ NODE_VECTOR_MATH_TANGENT
@ NODE_VECTOR_MATH_DISTANCE
@ NODE_VECTOR_MATH_FLOOR
@ NODE_VECTOR_MATH_SNAP
@ NODE_VECTOR_MATH_SINE
@ NODE_VECTOR_MATH_FRACTION
@ NODE_VECTOR_MATH_PROJECT
@ NODE_VECTOR_MATH_MULTIPLY
@ NODE_VECTOR_MATH_SCALE
@ NODE_VECTOR_MATH_MAXIMUM
@ NODE_VECTOR_MATH_FACEFORWARD
@ NODE_VECTOR_MATH_SUBTRACT
@ NODE_VECTOR_MATH_MULTIPLY_ADD
@ NODE_VECTOR_MATH_MINIMUM
@ NODE_VECTOR_ROTATE_TYPE_AXIS
@ NODE_VECTOR_ROTATE_TYPE_AXIS_Z
@ NODE_VECTOR_ROTATE_TYPE_AXIS_X
@ NODE_VECTOR_ROTATE_TYPE_EULER_XYZ
@ NODE_VECTOR_ROTATE_TYPE_AXIS_Y
@ NODE_MATH_SINH
@ NODE_MATH_SMOOTH_MIN
@ NODE_MATH_TRUNC
@ NODE_MATH_COSH
@ NODE_MATH_SIGN
@ NODE_MATH_DEGREES
@ NODE_MATH_MODULO
@ NODE_MATH_ABSOLUTE
@ NODE_MATH_DIVIDE
@ NODE_MATH_SINE
@ NODE_MATH_FLOORED_MODULO
@ NODE_MATH_ARCTAN2
@ NODE_MATH_ARCCOSINE
@ NODE_MATH_MULTIPLY_ADD
@ NODE_MATH_POWER
@ NODE_MATH_WRAP
@ NODE_MATH_ARCTANGENT
@ NODE_MATH_MINIMUM
@ NODE_MATH_SQRT
@ NODE_MATH_CEIL
@ NODE_MATH_TANH
@ NODE_MATH_GREATER_THAN
@ NODE_MATH_ADD
@ NODE_MATH_FRACTION
@ NODE_MATH_EXPONENT
@ NODE_MATH_LESS_THAN
@ NODE_MATH_ARCSINE
@ NODE_MATH_MAXIMUM
@ NODE_MATH_LOGARITHM
@ NODE_MATH_COMPARE
@ NODE_MATH_INV_SQRT
@ NODE_MATH_MULTIPLY
@ NODE_MATH_PINGPONG
@ NODE_MATH_ROUND
@ NODE_MATH_FLOOR
@ NODE_MATH_SUBTRACT
@ NODE_MATH_COSINE
@ NODE_MATH_SNAP
@ NODE_MATH_TANGENT
@ NODE_MATH_SMOOTH_MAX
@ NODE_MATH_RADIANS
@ NODE_CLAMP_RANGE
@ NODE_CLAMP_MINMAX
@ NODE_MAP_RANGE_STEPPED
@ NODE_MAP_RANGE_SMOOTHERSTEP
@ NODE_MAP_RANGE_SMOOTHSTEP
@ NODE_MAP_RANGE_LINEAR
@ NODE_COMBSEP_COLOR_RGB
@ NODE_COMBSEP_COLOR_HSV
@ NODE_COMBSEP_COLOR_HSL
@ NODE_MAPPING_TYPE_POINT
@ NODE_MAPPING_TYPE_VECTOR
@ NODE_MAPPING_TYPE_TEXTURE
@ NODE_MAPPING_TYPE_NORMAL
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 producing a negative Combine Generate a color from its and blue Hue Saturation Apply a color transformation in the HSV color model Specular Similar to the Principled BSDF node but uses the specular workflow instead of which functions by specifying the facing(along normal) reflection color. Energy is not conserved
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define output
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
void constant_fold(const ConstantFolder &folder)
void attributes(Shader *shader, AttributeRequestSet *attributes)
static AttributeStandard name_standard(const char *name)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
virtual bool has_bump()
ClosureType closure
BsdfBaseNode(const NodeType *node_type)
BsdfNode(const NodeType *node_type)
void compile(SVMCompiler &compiler, ShaderInput *bsdf_y, ShaderInput *bsdf_z, ShaderInput *data_y=nullptr, ShaderInput *data_z=nullptr, ShaderInput *data_w=nullptr)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
static bool colorspace_is_data(ustring colorspace)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void make_one() const
void make_constant_clamp(float value, bool clamp) const
void discard() const
void bypass(ShaderOutput *output) const
void bypass_or_discard(ShaderInput *input) const
void fold_mapping(NodeMappingType type) const
ShaderGraph *const graph
void fold_mix_float(bool clamp_factor, bool clamp) const
bool all_inputs_constant() const
bool try_bypass_or_make_constant(ShaderInput *input, bool clamp=false) const
void make_zero() const
bool is_zero(ShaderInput *input) const
bool is_one(ShaderInput *input) const
void fold_math(NodeMathType type) const
void make_constant(float value) const
ShaderOutput *const output
void fold_mix(NodeMix type, bool clamp) const
void fold_vector_math(NodeVectorMathType type) const
void fold_mix_color(NodeMix type, bool clamp_factor, bool clamp) const
void constant_fold(const ConstantFolder &folder)
float value_float
float3 value_vector
ConvertNode(SocketType::Type from, SocketType::Type to, bool autoconvert=false)
float3 value_color
CurvesNode(const NodeType *node_type)
void compile(SVMCompiler &compiler, int type, ShaderInput *value_in, ShaderOutput *value_out)
void constant_fold(const ConstantFolder &folder, ShaderInput *value_in)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
ImageParams image_params() const
ShaderNode * clone(ShaderGraph *graph) const
void attributes(Shader *shader, AttributeRequestSet *attributes)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void attributes(Shader *shader, AttributeRequestSet *attributes)
virtual void get_uv_tiles(ustring map, unordered_set< int > &tiles)=0
void attributes(Shader *shader, AttributeRequestSet *attributes)
void simplify_settings(Scene *scene)
void attributes(Shader *shader, AttributeRequestSet *attributes)
ShaderNode * clone(ShaderGraph *graph) const
int svm_slot(const int tile_index=0) const
ImageHandle add_image(const string &filename, const ImageParams &params)
bool is_float() const
InterpolationType interpolation
ExtensionType extension
ImageParams image_params() const
void attributes(Shader *shader, AttributeRequestSet *attributes)
void cull_tiles(Scene *scene, ShaderGraph *graph)
ShaderNode * clone(ShaderGraph *graph) const
void constant_fold(const ConstantFolder &folder)
int add_ies(const string &ies)
int add_ies_from_file(const string &filename)
void remove_ies(int slot)
void expand(ShaderGraph *graph)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void expand(ShaderGraph *graph)
void attributes(Shader *shader, AttributeRequestSet *attributes)
void simplify_settings(Scene *scene)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void attributes(Shader *shader, AttributeRequestSet *attributes)
void add(ShaderNode *node, const char *name, bool isfilepath=false)
Definition osl.cpp:1351
void parameter_array(const char *name, const float f[], int arraylen)
Definition osl.cpp:1373
void parameter_texture_ies(const char *name, int svm_slot)
Definition osl.cpp:1385
ShaderType output_type()
Definition scene/osl.h:154
void parameter_texture(const char *name, ustring filename, ustring colorspace)
Definition osl.cpp:1377
void parameter(ShaderNode *node, const char *name)
Definition osl.cpp:1353
bool background
Definition scene/osl.h:159
void parameter_color_array(const char *name, const array< float3 > &f)
Definition osl.cpp:1375
Scene * scene
Definition scene/osl.h:160
void parameter_color(const char *name, float3 f)
Definition osl.cpp:1357
string bytecode_hash
void add_input(ustring name, SocketType::Type type, const int flags=0)
static OSLNode * create(ShaderGraph *graph, size_t num_inputs, const OSLNode *from=NULL)
ShaderNode * clone(ShaderGraph *graph) const
void add_output(ustring name, SocketType::Type type)
char * input_default_value()
string filepath
virtual void simplify_settings(Scene *scene)
void attributes(Shader *shader, AttributeRequestSet *attributes)
ImageParams image_params() const
ShaderNode * clone(ShaderGraph *graph) const
void attributes(Shader *shader, AttributeRequestSet *attributes)
void attributes(Shader *shader, AttributeRequestSet *attributes)
void simplify_settings(Scene *scene)
void attributes(Shader *shader, AttributeRequestSet *attributes)
void attributes(Shader *shader, AttributeRequestSet *attributes)
void attributes(Shader *shader, AttributeRequestSet *attributes)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
ShaderGraph * current_graph
Definition scene/svm.h:121
void add_node(ShaderNodeType type, int a=0, int b=0, int c=0)
Definition svm.cpp:393
bool background
Definition scene/svm.h:122
void stack_clear_offset(SocketType::Type type, int offset)
Definition svm.cpp:239
int stack_assign_if_linked(ShaderInput *input)
Definition svm.cpp:302
uint encode_uchar4(uint x, uint y=0, uint z=0, uint w=0)
Definition svm.cpp:378
uint attribute_standard(ustring name)
Definition svm.cpp:422
void stack_link(ShaderInput *input, ShaderOutput *output)
Definition svm.cpp:320
ShaderType output_type()
Definition scene/svm.h:115
uint closure_mix_weight_offset()
Definition scene/svm.h:106
bool is_linked(ShaderInput *input)
Definition svm.cpp:297
uint get_bump_state_offset()
Definition scene/svm.h:110
uint attribute(ustring name)
Definition svm.cpp:412
Scene * scene
Definition scene/svm.h:120
int stack_find_offset(int size)
Definition svm.cpp:199
int stack_assign(ShaderOutput *output)
Definition svm.cpp:287
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
T * create_node(Args &&...args)
ShaderNode * add(ShaderNode *node)
SocketType::Type type() const
ShaderOutput * link
void disconnect()
const SocketType & socket_type
float linear_rgb_to_gray(float3 c)
float3 rec709_to_scene_linear(float3 c)
ShaderInput * input(const char *name)
ShaderNodeSpecialType special_type
ShaderBump bump
ShaderOutput * output(const char *name)
virtual void compile(SVMCompiler &compiler)=0
virtual void attributes(Shader *shader, AttributeRequestSet *attributes)
vector< ShaderInput * > links
ShaderNode * parent
void simplify_settings(Scene *scene)
float get_sun_size()
float get_sun_average_radiance()
void attributes(Shader *shader, AttributeRequestSet *attributes)
void attributes(Shader *shader, AttributeRequestSet *attributes)
void compile_end(SVMCompiler &compiler, ShaderInput *vector_in, int vector_offset)
Transform compute_transform()
Mapping x_mapping
Mapping z_mapping
void compile(SVMCompiler &compiler, int offset_in, int offset_out)
Mapping y_mapping
int compile_begin(SVMCompiler &compiler, ShaderInput *vector_in)
TextureMapping tex_mapping
void attributes(Shader *shader, AttributeRequestSet *attributes)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void constant_fold(const ConstantFolder &folder)
void attributes(Shader *shader, AttributeRequestSet *attributes)
void expand(ShaderGraph *graph)
void constant_fold(const ConstantFolder &folder)
void attributes(Shader *shader, AttributeRequestSet *attributes)
void expand(ShaderGraph *graph)
void attributes(Shader *shader, AttributeRequestSet *attributes)
ClosureType closure
void compile(SVMCompiler &compiler, ShaderInput *density, ShaderInput *param1=nullptr, ShaderInput *param2=nullptr)
VolumeNode(const NodeType *node_type)
void push_back_slow(const T &t)
ccl_device float3 svm_combine_color(NodeCombSepColorType type, float3 color)
Definition color_util.h:322
ccl_device float3 svm_separate_color(NodeCombSepColorType type, float3 color)
Definition color_util.h:335
ccl_device_noinline_cpu float3 svm_mix(NodeMix type, float t, float3 c1, float3 c2)
Definition color_util.h:256
ccl_device_noinline_cpu float3 svm_mix_clamped_factor(NodeMix type, float t, float3 c1, float3 c2)
Definition color_util.h:304
ccl_device_inline float3 svm_brightness_contrast(float3 color, float brightness, float contrast)
Definition color_util.h:310
CCL_NAMESPACE_BEGIN ustring u_colorspace_auto
ustring u_colorspace_raw
local_group_size(16, 16) .push_constant(Type b
OperationNode * node
#define cosf(x)
#define expf(x)
#define tanf(x)
#define CCL_NAMESPACE_END
ccl_device_forceinline float4 make_float4(const float x, const float y, const float z, const float w)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define atan2f(x, y)
#define NULL
#define fmodf(x, y)
#define acosf(x)
ccl_device_forceinline float2 make_float2(const float x, const float y)
#define copysignf(x, y)
#define __float_as_int(x)
#define fabsf(x)
#define __float_as_uint(x)
draw_view in_light_buf[] float
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt)
Definition frames.inl:1166
uint col
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition invert.h:9
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
ccl_global const KernelWorkTile * tile
@ NODE_ENVIRONMENT_MIRROR_BALL
@ NODE_ENVIRONMENT_EQUIRECTANGULAR
@ NODE_INFO_OB_INDEX
@ NODE_INFO_MAT_INDEX
@ NODE_INFO_OB_RANDOM
@ NODE_INFO_OB_COLOR
@ NODE_INFO_OB_LOCATION
@ NODE_INFO_OB_ALPHA
@ NODE_ATTR_OUTPUT_FLOAT
@ NODE_ATTR_OUTPUT_FLOAT_ALPHA
@ NODE_ATTR_OUTPUT_FLOAT3
ShaderNodeType
NodeBumpOffset
@ NODE_BUMP_OFFSET_DY
@ NODE_BUMP_OFFSET_CENTER
@ NODE_BUMP_OFFSET_DX
@ NODE_WAVE_BANDS_DIRECTION_Z
@ NODE_WAVE_BANDS_DIRECTION_DIAGONAL
@ NODE_WAVE_BANDS_DIRECTION_Y
@ NODE_WAVE_BANDS_DIRECTION_X
NodeMappingType
@ NODE_INFO_CURVE_IS_STRAND
@ NODE_INFO_CURVE_TANGENT_NORMAL
@ NODE_INFO_CURVE_THICKNESS
@ NODE_PRINCIPLED_HAIR_CHIANG
@ NODE_PRINCIPLED_HAIR_HUANG
@ NODE_NOISE_FBM
@ NODE_NOISE_HYBRID_MULTIFRACTAL
@ NODE_NOISE_RIDGED_MULTIFRACTAL
@ NODE_NOISE_HETERO_TERRAIN
@ NODE_NOISE_MULTIFRACTAL
@ NODE_AO_INSIDE
@ NODE_AO_GLOBAL_RADIUS
@ NODE_AO_ONLY_LOCAL
@ NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT
@ NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD
@ NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA
@ NODE_GABOR_TYPE_2D
@ NODE_GABOR_TYPE_3D
@ NODE_TANGENT_AXIS_Y
@ NODE_TANGENT_AXIS_X
@ NODE_TANGENT_AXIS_Z
@ NODE_PRINCIPLED_HAIR_REFLECTANCE
@ NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION
@ NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION
@ NODE_TEXCO_VOLUME_GENERATED
@ NODE_TEXCO_REFLECTION
@ NODE_TEXCO_WINDOW
@ NODE_TEXCO_OBJECT
@ NODE_TEXCO_DUPLI_UV
@ NODE_TEXCO_DUPLI_GENERATED
@ NODE_TEXCO_CAMERA
@ NODE_TEXCO_NORMAL
@ SHADER_TYPE_SURFACE
@ SHADER_TYPE_VOLUME
@ SHADER_TYPE_DISPLACEMENT
@ NODE_VORONOI_SMOOTH_F1
@ NODE_VORONOI_N_SPHERE_RADIUS
@ NODE_VORONOI_F1
@ NODE_VORONOI_F2
@ NODE_VORONOI_DISTANCE_TO_EDGE
@ NODE_GEOM_N
@ NODE_GEOM_T
@ NODE_GEOM_uv
@ NODE_GEOM_P
@ NODE_GEOM_Ng
@ NODE_GEOM_I
@ NODE_INFO_PAR_SIZE
@ NODE_INFO_PAR_LOCATION
@ NODE_INFO_PAR_RANDOM
@ NODE_INFO_PAR_VELOCITY
@ NODE_INFO_PAR_INDEX
@ NODE_INFO_PAR_ANGULAR_VELOCITY
@ NODE_INFO_PAR_AGE
@ NODE_INFO_PAR_LIFETIME
@ NODE_INFO_PAR_ROTATION
@ NODE_WAVE_BANDS
@ NODE_WAVE_RINGS
@ NODE_IMAGE_COMPRESS_AS_SRGB
@ NODE_IMAGE_ALPHA_UNASSOCIATE
@ NODE_VORONOI_EUCLIDEAN
@ NODE_VORONOI_MANHATTAN
@ NODE_VORONOI_CHEBYCHEV
@ NODE_VORONOI_MINKOWSKI
@ NODE_SKY_PREETHAM
@ NODE_SKY_NISHITA
@ NODE_SKY_HOSEK
@ NODE_WAVE_PROFILE_TRI
@ NODE_WAVE_PROFILE_SIN
@ NODE_WAVE_PROFILE_SAW
@ NODE_TEX_VOXEL_SPACE_WORLD
@ NODE_TEX_VOXEL_SPACE_OBJECT
@ NODE_MIX_DIV
@ NODE_MIX_SOFT
@ NODE_MIX_CLAMP
@ NODE_MIX_COL
@ NODE_MIX_LIGHT
@ NODE_MIX_MUL
@ NODE_MIX_DIFF
@ NODE_MIX_BURN
@ NODE_MIX_SUB
@ NODE_MIX_LINEAR
@ NODE_MIX_DARK
@ NODE_MIX_SAT
@ NODE_MIX_EXCLUSION
@ NODE_MIX_SCREEN
@ NODE_MIX_HUE
@ NODE_MIX_BLEND
@ NODE_MIX_OVERLAY
@ NODE_MIX_DODGE
@ NODE_MIX_VAL
@ NODE_MIX_ADD
@ NODE_LP_ray_depth
@ NODE_LP_shadow
@ NODE_LP_backfacing
@ NODE_LP_ray_glossy
@ NODE_LP_camera
@ NODE_LP_glossy
@ NODE_LP_transmission
@ NODE_LP_singular
@ NODE_LP_diffuse
@ NODE_LP_ray_diffuse
@ NODE_LP_volume_scatter
@ NODE_LP_ray_transmission
@ NODE_LP_ray_length
@ NODE_LP_ray_transparent
@ NODE_LP_reflection
#define SVM_STACK_INVALID
@ 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_BSDF_DIFFUSE_ID
@ CLOSURE_BSSRDF_BURLEY_ID
@ CLOSURE_BSDF_PRINCIPLED_ID
@ CLOSURE_BSDF_SHEEN_ID
@ CLOSURE_BSDF_TRANSPARENT_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_HAIR_HUANG_ID
@ CLOSURE_BSDF_MICROFACET_BECKMANN_ID
@ CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID
@ CLOSURE_BSDF_F82_CONDUCTOR
@ CLOSURE_BSDF_RAY_PORTAL_ID
@ CLOSURE_BSDF_GLOSSY_TOON_ID
@ CLOSURE_BSDF_HAIR_CHIANG_ID
@ CLOSURE_VOLUME_ABSORPTION_ID
@ CLOSURE_BSDF_HAIR_REFLECTION_ID
@ CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID
@ CLOSURE_BSDF_TRANSLUCENT_ID
@ CLOSURE_BSDF_ASHIKHMIN_VELVET_ID
@ NODE_INFO_POINT_RADIUS
@ NODE_INFO_POINT_POSITION
@ NODE_VECTOR_TRANSFORM_TYPE_NORMAL
@ NODE_VECTOR_TRANSFORM_TYPE_VECTOR
@ NODE_VECTOR_TRANSFORM_TYPE_POINT
@ NODE_IMAGE_PROJ_SPHERE
@ NODE_IMAGE_PROJ_TUBE
@ NODE_IMAGE_PROJ_BOX
@ NODE_IMAGE_PROJ_FLAT
@ NODE_BLEND_QUADRATIC
@ NODE_BLEND_DIAGONAL
@ NODE_BLEND_EASING
@ NODE_BLEND_RADIAL
@ NODE_BLEND_SPHERICAL
@ NODE_BLEND_QUADRATIC_SPHERE
@ NODE_BLEND_LINEAR
#define CLOSURE_WEIGHT_CUTOFF
@ NODE_TANGENT_RADIAL
@ NODE_TANGENT_UVMAP
@ NODE_WAVE_RINGS_DIRECTION_Y
@ NODE_WAVE_RINGS_DIRECTION_SPHERICAL
@ NODE_WAVE_RINGS_DIRECTION_X
@ NODE_WAVE_RINGS_DIRECTION_Z
@ NODE_LAYER_WEIGHT_FACING
@ NODE_LAYER_WEIGHT_FRESNEL
@ NODE_NORMAL_MAP_TANGENT
@ NODE_NORMAL_MAP_WORLD
@ NODE_NORMAL_MAP_BLENDER_WORLD
@ NODE_NORMAL_MAP_BLENDER_OBJECT
@ NODE_NORMAL_MAP_OBJECT
@ NODE_CONVERT_IF
@ NODE_CONVERT_CI
@ NODE_CONVERT_CF
@ NODE_CONVERT_VF
@ NODE_CONVERT_VI
@ NODE_CONVERT_FI
@ NODE_CONVERT_IV
@ NODE_CONVERT_FV
@ NODE_LIGHT_FALLOFF_QUADRATIC
@ NODE_LIGHT_FALLOFF_LINEAR
@ NODE_LIGHT_FALLOFF_CONSTANT
@ ATTR_STD_CURVE_INTERCEPT
@ ATTR_STD_GENERATED_TRANSFORM
@ ATTR_STD_UV
@ ATTR_STD_VOLUME_TEMPERATURE
@ ATTR_STD_VERTEX_NORMAL
@ ATTR_STD_UV_TANGENT
@ ATTR_STD_NONE
@ ATTR_STD_POINT_RANDOM
@ ATTR_STD_VERTEX_COLOR
@ ATTR_STD_VOLUME_DENSITY
@ ATTR_STD_VOLUME_FLAME
@ ATTR_STD_PTEX_FACE_ID
@ ATTR_STD_VOLUME_COLOR
@ ATTR_STD_UV_TANGENT_SIGN
@ ATTR_STD_CURVE_RANDOM
@ ATTR_STD_PTEX_UV
@ ATTR_STD_POINTINESS
@ ATTR_STD_GENERATED
@ ATTR_STD_CURVE_LENGTH
@ ATTR_STD_RANDOM_PER_ISLAND
@ ATTR_STD_PARTICLE
CCL_NAMESPACE_BEGIN ccl_device float3 svm_mapping(NodeMappingType type, float3 vector, float3 location, float3 rotation, float3 scale)
ccl_device_inline float average(const float2 a)
ccl_device_inline float reduce_max(const float2 a)
ccl_device_inline float2 interp(const float2 a, const float2 b, float t)
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
CCL_NAMESPACE_BEGIN ccl_device void svm_vector_math(ccl_private float *value, ccl_private float3 *vector, NodeVectorMathType type, float3 a, float3 b, float3 c, float param1)
Definition math_util.h:9
ccl_device float svm_math(NodeMathType type, float a, float b, float c)
Definition math_util.h:105
ccl_device float3 svm_math_blackbody_color_rec709(float t)
Definition math_util.h:195
ccl_device_inline float3 svm_math_gamma_color(float3 color, float gamma)
Definition math_util.h:229
#define T
#define R
#define T2
Definition md5.cpp:19
#define M_PI_F
Definition mikk_util.hh:15
#define vector3
color rgb_ramp_lookup(color ramp[], float at, int interpolate, int extrapolate)
#define SOCKET_IN_NORMAL(name, ui_name, default_value,...)
Definition node_type.h:334
#define SOCKET_OUT_POINT(name, ui_name)
Definition node_type.h:381
#define SOCKET_OUT_FLOAT(name, ui_name)
Definition node_type.h:369
#define SOCKET_OUT_COLOR(name, ui_name)
Definition node_type.h:373
#define SOCKET_FLOAT(name, ui_name, default_value,...)
Definition node_type.h:200
#define SOCKET_INT(name, ui_name, default_value,...)
Definition node_type.h:194
#define SOCKET_IN_COLOR(name, ui_name, default_value,...)
Definition node_type.h:310
#define SOCKET_FLOAT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:248
#define SOCKET_TRANSFORM(name, ui_name, default_value,...)
Definition node_type.h:214
#define SOCKET_OUT_NORMAL(name, ui_name)
Definition node_type.h:385
#define SOCKET_IN_FLOAT(name, ui_name, default_value,...)
Definition node_type.h:302
#define SOCKET_IN_CLOSURE(name, ui_name,...)
Definition node_type.h:350
#define SOCKET_OFFSETOF(T, name)
Definition node_type.h:175
#define SOCKET_INT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:246
#define SOCKET_VECTOR_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:254
#define SOCKET_IN_VECTOR(name, ui_name, default_value,...)
Definition node_type.h:318
#define NODE_DEFINE(structname)
Definition node_type.h:148
#define SOCKET_VECTOR(name, ui_name, default_value,...)
Definition node_type.h:204
#define SOCKET_IN_POINT(name, ui_name, default_value,...)
Definition node_type.h:326
#define SOCKET_COLOR_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:251
#define SOCKET_COLOR(name, ui_name, default_value,...)
Definition node_type.h:202
#define SOCKET_OUT_VECTOR(name, ui_name)
Definition node_type.h:377
#define SOCKET_IN_STRING(name, ui_name, default_value,...)
Definition node_type.h:342
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition node_type.h:192
#define SOCKET_IN_BOOLEAN(name, ui_name, default_value,...)
Definition node_type.h:291
#define SOCKET_STRING(name, ui_name, default_value,...)
Definition node_type.h:212
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
Definition node_type.h:216
#define SOCKET_OUT_CLOSURE(name, ui_name)
Definition node_type.h:389
ccl_device_inline float float_ramp_lookup(KernelGlobals kg, int offset, float f, bool interpolate, bool extrapolate, int table_size)
Definition ramp.h:17
@ SHADER_SPECIAL_TYPE_PROXY
@ SHADER_SPECIAL_TYPE_GEOMETRY
@ SHADER_SPECIAL_TYPE_OUTPUT_AOV
@ SHADER_SPECIAL_TYPE_COMBINE_CLOSURE
@ SHADER_SPECIAL_TYPE_BUMP
@ SHADER_SPECIAL_TYPE_AUTOCONVERT
@ SHADER_SPECIAL_TYPE_OUTPUT
@ SHADER_SPECIAL_TYPE_CLOSURE
@ SHADER_SPECIAL_TYPE_OSL
@ SHADER_BUMP_DX
@ SHADER_BUMP_DY
static void sky_texture_precompute_hosek(SunSky *sunsky, float3 dir, float turbidity, float ground_albedo)
struct SunSky SunSky
static float2 sky_spherical_coordinates(float3 dir)
static float sky_perez_function(float lam[6], float theta, float gamma)
#define TEXTURE_MAPPING_DEFINE(TextureNode)
static void sky_texture_precompute_preetham(SunSky *sunsky, float3 dir, float turbidity)
static void sky_texture_precompute_nishita(SunSky *sunsky, bool sun_disc, float sun_size, float sun_intensity, float sun_elevation, float sun_rotation, float altitude, float air_density, float dust_density)
#define M_PI_2_F
Definition sky_float3.h:20
#define M_2PI_F
Definition sky_float3.h:23
void SKY_arhosekskymodelstate_free(SKY_ArHosekSkyModelState *state)
SKY_ArHosekSkyModelState * SKY_arhosek_xyz_skymodelstate_alloc_init(const double turbidity, const double albedo, const double elevation)
void SKY_nishita_skymodel_precompute_sun(float sun_elevation, float angular_diameter, float altitude, float air_density, float dust_density, float *r_pixel_bottom, float *r_pixel_top)
static const int steps
#define min(a, b)
Definition sort.c:32
bool string_endswith(const string_view s, const string_view end)
Definition string.cpp:114
void insert(const char *x, int y)
Definition node_enum.h:21
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
float get_float(const SocketType &input) const
const NodeType * type
Definition graph/node.h:178
float3 get_float3(const SocketType &input) const
void set_owner(const NodeOwner *owner_)
SKY_ArHosekSkyModelConfiguration configs[11]
Definition sky_model.h:317
ImageManager * image_manager
Definition scene.h:140
ShaderManager * shader_manager
Definition scene.h:142
LightManager * light_manager
Definition scene.h:141
static size_t max_size()
Definition node_type.cpp:89
static bool is_float3(Type type)
static ustring type_name(Type type)
static void * zero_default_value()
Definition node_type.cpp:94
@ LINK_TEXTURE_UV
Definition node_type.h:68
@ LINK_TEXTURE_GENERATED
Definition node_type.h:66
@ LINK_TEXTURE_INCOMING
Definition node_type.h:69
@ LINK_POSITION
Definition node_type.h:72
float config_z[9]
float config_x[9]
float radiance_y
float nishita_data[10]
float radiance_z
float config_y[9]
float theta
float radiance_x
float4 y
Definition transform.h:24
float4 x
Definition transform.h:24
float4 z
Definition transform.h:24
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
Transform transform_transposed_inverse(const Transform &tfm)
ccl_device_inline Transform transform_identity()
Definition transform.h:296
ccl_device_inline Transform transform_euler(float3 euler)
Definition transform.h:289
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
float max
ccl_device_inline float sqr(float a)
Definition util/math.h:782
ccl_device_inline float4 float3_to_float4(const float3 a)
Definition util/math.h:540
ccl_device_inline int clamp(int a, int mn, int mx)
Definition util/math.h:379
@ IMAGE_ALPHA_ASSOCIATED
@ IMAGE_ALPHA_CHANNEL_PACKED
@ IMAGE_ALPHA_AUTO
@ IMAGE_ALPHA_IGNORE
@ IMAGE_ALPHA_UNASSOCIATED
#define TEX_IMAGE_MISSING_R
#define TEX_IMAGE_MISSING_B
@ INTERPOLATION_LINEAR
@ INTERPOLATION_SMART
@ INTERPOLATION_CLOSEST
@ INTERPOLATION_CUBIC
@ EXTENSION_REPEAT
@ EXTENSION_CLIP
@ EXTENSION_EXTEND
@ EXTENSION_MIRROR
#define TEX_IMAGE_MISSING_G
ccl_device_inline size_t align_up(size_t offset, size_t alignment)
Definition util/types.h:48
ccl_device_inline size_t divide_up(size_t x, size_t y)
Definition util/types.h:53