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