Fix T73938: Cycles Vertex Color wrong if no layer is specified
authorPhilipp Oeser <info@graphics-engineer.com>
Tue, 18 Feb 2020 16:19:16 +0000 (17:19 +0100)
committerPhilipp Oeser <info@graphics-engineer.com>
Wed, 19 Feb 2020 11:10:33 +0000 (12:10 +0100)
The node would render black in this case (but should use the
'active_render' layer choosen in the object data properties -- this is
now in line to how this is handled for e.g. UVs)

This introduces ATTR_STD_VERTEX_COLOR and uses this thoughout, if no
particular layer is specified in the node.

Maniphest Tasks: T73938

Differential Revision: https://developer.blender.org/D6887

intern/cycles/blender/blender_mesh.cpp
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/shaders/node_vertex_color.osl
intern/cycles/render/attribute.cpp
intern/cycles/render/nodes.cpp

index 4be07ac5e8eeea100394f9387f9204efe4635567..509da1601f34de63a47953e3dc80f41e2df733c5 100644 (file)
@@ -285,14 +285,27 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
     BL::Mesh::vertex_colors_iterator l;
 
     for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
-      if (!mesh->need_attribute(scene, ustring(l->name().c_str())))
+      const bool active_render = l->active_render();
+      AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
+      ustring vcol_name = ustring(l->name().c_str());
+
+      const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
+                           mesh->need_attribute(scene, vcol_std);
+
+      if (!need_vcol) {
         continue;
+      }
 
-      Attribute *attr = mesh->subd_attributes.add(
-          ustring(l->name().c_str()), TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
+      Attribute *vcol_attr = NULL;
+      if (active_render) {
+        vcol_attr = mesh->subd_attributes.add(vcol_std, vcol_name);
+      }
+      else {
+        vcol_attr = mesh->subd_attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
+      }
 
       BL::Mesh::polygons_iterator p;
-      uchar4 *cdata = attr->data_uchar4();
+      uchar4 *cdata = vcol_attr->data_uchar4();
 
       for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
         int n = p->loop_total();
@@ -307,14 +320,27 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
   else {
     BL::Mesh::vertex_colors_iterator l;
     for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
-      if (!mesh->need_attribute(scene, ustring(l->name().c_str())))
+      const bool active_render = l->active_render();
+      AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
+      ustring vcol_name = ustring(l->name().c_str());
+
+      const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
+                           mesh->need_attribute(scene, vcol_std);
+
+      if (!need_vcol) {
         continue;
+      }
 
-      Attribute *attr = mesh->attributes.add(
-          ustring(l->name().c_str()), TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
+      Attribute *vcol_attr = NULL;
+      if (active_render) {
+        vcol_attr = mesh->attributes.add(vcol_std, vcol_name);
+      }
+      else {
+        vcol_attr = mesh->attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
+      }
 
       BL::Mesh::loop_triangles_iterator t;
-      uchar4 *cdata = attr->data_uchar4();
+      uchar4 *cdata = vcol_attr->data_uchar4();
 
       for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
         int3 li = get_int3(t->loops());
index bf34450df4b0a1f2b582fa235f449767a27c3f51..68cb1e974f083b57364f35338e8404fde184c4b3 100644 (file)
@@ -753,6 +753,7 @@ typedef enum AttributeStandard {
   ATTR_STD_UV,
   ATTR_STD_UV_TANGENT,
   ATTR_STD_UV_TANGENT_SIGN,
+  ATTR_STD_VERTEX_COLOR,
   ATTR_STD_GENERATED,
   ATTR_STD_GENERATED_TRANSFORM,
   ATTR_STD_POSITION_UNDEFORMED,
index 70843b5543a7a3434315bd78d365f92ba6259ed0..ffaf7a2f72082029421c40f852903b3c7871fda9 100644 (file)
@@ -22,7 +22,16 @@ shader node_vertex_color(string bump_offset = "center",
                          output float Alpha = 0.0)
 {
   float vertex_color[4];
-  if (getattribute(layer_name, vertex_color)) {
+  string vertex_color_layer;
+
+  if (layer_name == "") {
+    vertex_color_layer = "geom:vertex_color";
+  }
+  else {
+    vertex_color_layer = layer_name;
+  }
+
+  if (getattribute(vertex_color_layer, vertex_color)) {
     Color = color(vertex_color[0], vertex_color[1], vertex_color[2]);
     Alpha = vertex_color[3];
 
index 05c0b5693bcac513889c3a5c4cba1f43462ddd00..4fbf831087f24fe9963101a589dc4882654d5a29 100644 (file)
@@ -301,6 +301,8 @@ const char *Attribute::standard_name(AttributeStandard std)
       return "tangent";
     case ATTR_STD_UV_TANGENT_SIGN:
       return "tangent_sign";
+    case ATTR_STD_VERTEX_COLOR:
+      return "vertex_color";
     case ATTR_STD_POSITION_UNDEFORMED:
       return "undeformed";
     case ATTR_STD_POSITION_UNDISPLACED:
@@ -480,6 +482,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
       case ATTR_STD_UV_TANGENT_SIGN:
         attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CORNER);
         break;
+      case ATTR_STD_VERTEX_COLOR:
+        attr = add(name,TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
+        break;
       case ATTR_STD_GENERATED:
       case ATTR_STD_POSITION_UNDEFORMED:
       case ATTR_STD_POSITION_UNDISPLACED:
index 41b4b05ba19b3b8c3cd4c13d968875a7029f842f..9c909c2131faad1ab7b0b67fe68c9237fdcbb1ae 100644 (file)
@@ -4519,7 +4519,10 @@ VertexColorNode::VertexColorNode() : ShaderNode(node_type)
 void VertexColorNode::attributes(Shader *shader, AttributeRequestSet *attributes)
 {
   if (!(output("Color")->links.empty() && output("Alpha")->links.empty())) {
-    attributes->add_standard(layer_name);
+    if (layer_name != "")
+      attributes->add_standard(layer_name);
+    else
+      attributes->add(ATTR_STD_VERTEX_COLOR);
   }
   ShaderNode::attributes(shader, attributes);
 }
@@ -4528,7 +4531,14 @@ void VertexColorNode::compile(SVMCompiler &compiler)
 {
   ShaderOutput *color_out = output("Color");
   ShaderOutput *alpha_out = output("Alpha");
-  int layer_id = compiler.attribute(layer_name);
+  int layer_id = 0;
+
+  if (layer_name != "") {
+    layer_id = compiler.attribute(layer_name);
+  }
+  else {
+    layer_id = compiler.attribute(ATTR_STD_VERTEX_COLOR);
+  }
 
   ShaderNodeType node;
 
@@ -4555,7 +4565,19 @@ void VertexColorNode::compile(OSLCompiler &compiler)
   else {
     compiler.parameter("bump_offset", "center");
   }
-  compiler.parameter("layer_name", layer_name.c_str());
+
+  if (layer_name.empty()) {
+    compiler.parameter("layer_name", ustring("geom:vertex_color"));
+  }
+  else {
+    if (Attribute::name_standard(layer_name.c_str()) != ATTR_STD_NONE) {
+      compiler.parameter("name", (string("geom:") + layer_name.c_str()).c_str());
+    }
+    else {
+      compiler.parameter("layer_name", layer_name.c_str());
+    }
+  }
+
   compiler.add(this, "node_vertex_color");
 }