[Bf-blender-cvs] [dc1ed9c1aa0] blender-v3.4-release: Cycles: add OSL support for hiding input socket value

Brecht Van Lommel noreply at git.blender.org
Wed Nov 23 19:35:10 CET 2022


Commit: dc1ed9c1aa0d25ba39ba5b5a8819f4318f829227
Author: Brecht Van Lommel
Date:   Wed Nov 23 18:02:45 2022 +0100
Branches: blender-v3.4-release
https://developer.blender.org/rBdc1ed9c1aa0d25ba39ba5b5a8819f4318f829227

Cycles: add OSL support for hiding input socket value

When either initializing with a non-constant value, or using the standard
[[ string widget = "null" ]] metadata. This can be used for inputs like
normals and texture coordinates, where you don't want to default to a
constant value.

In previous OSL versions the input value was automatically ignore when it
was left unchanged for such inputs. However that's no longer the case in
the latest version, breaking existing nodes. There is no good entirely
backwards compatible fix, but I believe the new behavior is better and will
keep most existing cases working.

Fix T102450: OSL node with normal input not working

===================================================================

M	intern/cycles/blender/python.cpp
M	intern/cycles/graph/node_type.h
M	intern/cycles/scene/osl.cpp
M	intern/cycles/scene/shader_nodes.cpp
M	intern/cycles/scene/shader_nodes.h

===================================================================

diff --git a/intern/cycles/blender/python.cpp b/intern/cycles/blender/python.cpp
index 9e42f6b8b60..1e9478ea32d 100644
--- a/intern/cycles/blender/python.cpp
+++ b/intern/cycles/blender/python.cpp
@@ -478,6 +478,7 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
 
     /* Read metadata. */
     bool is_bool_param = false;
+    bool hide_value = !param->validdefault;
     ustring param_label = param->name;
 
     for (const OSL::OSLQuery::Parameter &metadata : param->metadata) {
@@ -487,6 +488,9 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
           if (metadata.sdefault[0] == "boolean" || metadata.sdefault[0] == "checkBox") {
             is_bool_param = true;
           }
+          else if (metadata.sdefault[0] == "null") {
+            hide_value = true;
+          }
         }
         else if (metadata.name == "label") {
           /* Socket label. */
@@ -596,6 +600,9 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
             if (b_sock.name() != param_label) {
               b_sock.name(param_label.string());
             }
+            if (b_sock.hide_value() != hide_value) {
+              b_sock.hide_value(hide_value);
+            }
             used_sockets.insert(b_sock.ptr.data);
             found_existing = true;
           }
@@ -635,6 +642,8 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
         set_boolean(b_sock.ptr, "default_value", default_boolean);
       }
 
+      b_sock.hide_value(hide_value);
+
       used_sockets.insert(b_sock.ptr.data);
     }
   }
diff --git a/intern/cycles/graph/node_type.h b/intern/cycles/graph/node_type.h
index 9101b51bb9f..7725396e4f1 100644
--- a/intern/cycles/graph/node_type.h
+++ b/intern/cycles/graph/node_type.h
@@ -66,7 +66,9 @@ struct SocketType {
     LINK_NORMAL = (1 << 8),
     LINK_POSITION = (1 << 9),
     LINK_TANGENT = (1 << 10),
-    DEFAULT_LINK_MASK = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10)
+    LINK_OSL_INITIALIZER = (1 << 11),
+    DEFAULT_LINK_MASK = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) |
+                        (1 << 10) | (1 << 11)
   };
 
   ustring name;
diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp
index 93839facdbe..2ff36ff7fca 100644
--- a/intern/cycles/scene/osl.cpp
+++ b/intern/cycles/scene/osl.cpp
@@ -525,6 +525,7 @@ OSLNode *OSLShaderManager::osl_node(ShaderGraph *graph,
 
     SocketType::Type socket_type;
 
+    /* Read type and default value. */
     if (param->isclosure) {
       socket_type = SocketType::CLOSURE;
     }
@@ -579,7 +580,21 @@ OSLNode *OSLShaderManager::osl_node(ShaderGraph *graph,
       node->add_output(param->name, socket_type);
     }
     else {
-      node->add_input(param->name, socket_type);
+      /* Detect if we should leave parameter initialization to OSL, either though
+       * not constant default or widget metadata. */
+      int socket_flags = 0;
+      if (!param->validdefault) {
+        socket_flags |= SocketType::LINK_OSL_INITIALIZER;
+      }
+      for (const OSL::OSLQuery::Parameter &metadata : param->metadata) {
+        if (metadata.type == TypeDesc::STRING) {
+          if (metadata.name == "widget" && metadata.sdefault[0] == "null") {
+            socket_flags |= SocketType::LINK_OSL_INITIALIZER;
+          }
+        }
+      }
+
+      node->add_input(param->name, socket_type, socket_flags);
     }
   }
 
@@ -702,8 +717,12 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
   foreach (ShaderInput *input, node->inputs) {
     if (!input->link) {
       /* checks to untangle graphs */
-      if (node_skip_input(node, input))
+      if (node_skip_input(node, input)) {
+        continue;
+      }
+      if (input->flags() & SocketType::LINK_OSL_INITIALIZER) {
         continue;
+      }
 
       string param_name = compatible_name(node, input);
       const SocketType &socket = input->socket_type;
diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp
index 2c1cd3ee737..c1189e3795c 100644
--- a/intern/cycles/scene/shader_nodes.cpp
+++ b/intern/cycles/scene/shader_nodes.cpp
@@ -7257,12 +7257,12 @@ char *OSLNode::input_default_value()
   return (char *)this + align_up(sizeof(OSLNode), 16) + inputs_size;
 }
 
-void OSLNode::add_input(ustring name, SocketType::Type socket_type)
+void OSLNode::add_input(ustring name, SocketType::Type socket_type, const int flags)
 {
   char *memory = input_default_value();
   size_t offset = memory - (char *)this;
   const_cast<NodeType *>(type)->register_input(
-      name, name, socket_type, offset, memory, NULL, NULL, SocketType::LINKABLE);
+      name, name, socket_type, offset, memory, NULL, NULL, flags | SocketType::LINKABLE);
 }
 
 void OSLNode::add_output(ustring name, SocketType::Type socket_type)
diff --git a/intern/cycles/scene/shader_nodes.h b/intern/cycles/scene/shader_nodes.h
index 3ab7b1041b5..0a5dd99e8bf 100644
--- a/intern/cycles/scene/shader_nodes.h
+++ b/intern/cycles/scene/shader_nodes.h
@@ -1525,7 +1525,7 @@ class OSLNode final : public ShaderNode {
   ShaderNode *clone(ShaderGraph *graph) const;
 
   char *input_default_value();
-  void add_input(ustring name, SocketType::Type type);
+  void add_input(ustring name, SocketType::Type type, const int flags = 0);
   void add_output(ustring name, SocketType::Type type);
 
   SHADER_NODE_NO_CLONE_CLASS(OSLNode)



More information about the Bf-blender-cvs mailing list