Shading: Add object color to Object Info node.
authorOmarSquircleArt <omar.squircleart@gmail.com>
Thu, 22 Aug 2019 12:26:09 +0000 (14:26 +0200)
committerOmarSquircleArt <omar.squircleart@gmail.com>
Thu, 22 Aug 2019 12:26:09 +0000 (14:26 +0200)
The object color property is added as an additional output in
the Object Info node.

Reviewers: brecht

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

22 files changed:
intern/cycles/blender/blender_object.cpp
intern/cycles/kernel/geom/geom_object.h
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/osl/osl_services.cpp
intern/cycles/kernel/osl/osl_services.h
intern/cycles/kernel/shaders/node_object_info.osl
intern/cycles/kernel/svm/svm_geometry.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/nodes.cpp
intern/cycles/render/object.cpp
intern/cycles/render/object.h
source/blender/draw/intern/draw_manager.c
source/blender/draw/intern/draw_manager.h
source/blender/draw/intern/draw_manager_data.c
source/blender/draw/intern/draw_manager_exec.c
source/blender/gpu/GPU_material.h
source/blender/gpu/GPU_shader_interface.h
source/blender/gpu/intern/gpu_codegen.c
source/blender/gpu/intern/gpu_shader_interface.c
source/blender/gpu/shaders/gpu_shader_material.glsl
source/blender/makesrna/intern/rna_object.c
source/blender/nodes/shader/nodes/node_shader_object_info.c

index ab47da9c1a27432ad9ddaf16ce264d83ce728497..b670922ac881b55495cdd338487a8631971b0cf0 100644 (file)
@@ -444,6 +444,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
   if (object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) {
     object->name = b_ob.name().c_str();
     object->pass_id = b_ob.pass_index();
+    object->color = get_float3(b_ob.color());
     object->tfm = tfm;
     object->motion.clear();
 
index f410e6e27e2b29a20298007eee33c06cef2ebca7..af4e6fbd89ba1ae17a155412a4ed06be3b9289d5 100644 (file)
@@ -227,6 +227,17 @@ ccl_device_inline float object_surface_area(KernelGlobals *kg, int object)
   return kernel_tex_fetch(__objects, object).surface_area;
 }
 
+/* Color of the object */
+
+ccl_device_inline float3 object_color(KernelGlobals *kg, int object)
+{
+  if (object == OBJECT_NONE)
+    return make_float3(0.0f, 0.0f, 0.0f);
+
+  const ccl_global KernelObject *kobject = &kernel_tex_fetch(__objects, object);
+  return make_float3(kobject->color[0], kobject->color[1], kobject->color[2]);
+}
+
 /* Pass ID number of object */
 
 ccl_device_inline float object_pass_id(KernelGlobals *kg, int object)
index f3f321e77dcc240274887fff236813fdd8c6deee..8aaa83045ea66f44b2cf4c6afc68145094746846 100644 (file)
@@ -1408,6 +1408,7 @@ typedef struct KernelObject {
   float surface_area;
   float pass_id;
   float random_number;
+  float color[3];
   int particle_index;
 
   float dupli_generated[3];
@@ -1420,11 +1421,9 @@ typedef struct KernelObject {
   uint patch_map_offset;
   uint attribute_map_offset;
   uint motion_offset;
-  uint pad1;
 
   float cryptomatte_object;
   float cryptomatte_asset;
-  float pad2, pad3;
 } KernelObject;
 static_assert_align(KernelObject, 16);
 
index 3850d0fe94b1c69b979425a8f9b6b280b1853c32..222475b37784cb1aa3d75a09e0efaec59b29da9c 100644 (file)
@@ -81,6 +81,7 @@ ustring OSLRenderServices::u_screen("screen");
 ustring OSLRenderServices::u_raster("raster");
 ustring OSLRenderServices::u_ndc("NDC");
 ustring OSLRenderServices::u_object_location("object:location");
+ustring OSLRenderServices::u_object_color("object:color");
 ustring OSLRenderServices::u_object_index("object:index");
 ustring OSLRenderServices::u_geom_dupli_generated("geom:dupli_generated");
 ustring OSLRenderServices::u_geom_dupli_uv("geom:dupli_uv");
@@ -668,6 +669,10 @@ bool OSLRenderServices::get_object_standard_attribute(
     float3 f = object_location(kg, sd);
     return set_attribute_float3(f, type, derivatives, val);
   }
+  else if (name == u_object_color) {
+    float3 f = object_color(kg, sd->object);
+    return set_attribute_float3(f, type, derivatives, val);
+  }
   else if (name == u_object_index) {
     float f = object_pass_id(kg, sd->object);
     return set_attribute_float(f, type, derivatives, val);
index 024ef656be162ee3dea62c85eec8d22ce1139d86..469c51887306331575660ad09f7115211b72c63c 100644 (file)
@@ -245,6 +245,7 @@ class OSLRenderServices : public OSL::RendererServices {
   static ustring u_raster;
   static ustring u_ndc;
   static ustring u_object_location;
+  static ustring u_object_color;
   static ustring u_object_index;
   static ustring u_geom_dupli_generated;
   static ustring u_geom_dupli_uv;
index 0904a30a53ff68e924daff1d7b9c0494a8a27bc8..350404bb747a9666077e9229fb557416e71d1b4f 100644 (file)
 #include "stdosl.h"
 
 shader node_object_info(output point Location = point(0.0, 0.0, 0.0),
+                        output color Color = color(1.0, 1.0, 1.0),
                         output float ObjectIndex = 0.0,
                         output float MaterialIndex = 0.0,
                         output float Random = 0.0)
 {
   getattribute("object:location", Location);
+  getattribute("object:color", Color);
   getattribute("object:index", ObjectIndex);
   getattribute("material:index", MaterialIndex);
   getattribute("object:random", Random);
index 4abe0831858a30b03b1300556061ebc8734e1d8c..019c6294082ca9fa53e80be1697eef3560eeb601 100644 (file)
@@ -113,6 +113,10 @@ ccl_device void svm_node_object_info(
       stack_store_float3(stack, out_offset, object_location(kg, sd));
       return;
     }
+    case NODE_INFO_OB_COLOR: {
+      stack_store_float3(stack, out_offset, object_color(kg, sd->object));
+      return;
+    }
     case NODE_INFO_OB_INDEX:
       data = object_pass_id(kg, sd->object);
       break;
index 6f41207412569d5bd38620ddc25b4faf008285e6..a3caa1ab68d2f44b5e2930f9802ed5f4b3123e2e 100644 (file)
@@ -161,6 +161,7 @@ typedef enum NodeGeometry {
 
 typedef enum NodeObjectInfo {
   NODE_INFO_OB_LOCATION,
+  NODE_INFO_OB_COLOR,
   NODE_INFO_OB_INDEX,
   NODE_INFO_MAT_INDEX,
   NODE_INFO_OB_RANDOM
index 3a5d65039c8afa07ebae0dccbfffbafae5169117..69c1c06f8461370e8aa07cf356daa84c03bc9f4f 100644 (file)
@@ -3940,6 +3940,7 @@ NODE_DEFINE(ObjectInfoNode)
   NodeType *type = NodeType::add("object_info", create, NodeType::SHADER);
 
   SOCKET_OUT_VECTOR(location, "Location");
+  SOCKET_OUT_COLOR(color, "Color");
   SOCKET_OUT_FLOAT(object_index, "Object Index");
   SOCKET_OUT_FLOAT(material_index, "Material Index");
   SOCKET_OUT_FLOAT(random, "Random");
@@ -3958,6 +3959,11 @@ void ObjectInfoNode::compile(SVMCompiler &compiler)
     compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_LOCATION, compiler.stack_assign(out));
   }
 
+  out = output("Color");
+  if (!out->links.empty()) {
+    compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_COLOR, compiler.stack_assign(out));
+  }
+
   out = output("Object Index");
   if (!out->links.empty()) {
     compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_INDEX, compiler.stack_assign(out));
index 6c6f88104125d83a652642bb171ee74d8f12184c..849329a086d4fe7dcb0cdddbdcc53e9ab2dbce66 100644 (file)
@@ -90,6 +90,7 @@ NODE_DEFINE(Object)
   SOCKET_NODE(mesh, "Mesh", &Mesh::node_type);
   SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
   SOCKET_UINT(visibility, "Visibility", ~0);
+  SOCKET_COLOR(color, "Color", make_float3(0.0f, 0.0f, 0.0f));
   SOCKET_UINT(random_id, "Random ID", 0);
   SOCKET_INT(pass_id, "Pass ID", 0);
   SOCKET_BOOLEAN(use_holdout, "Use Holdout", false);
@@ -371,6 +372,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
    */
   float uniform_scale;
   float surface_area = 0.0f;
+  float3 color = ob->color;
   float pass_id = ob->pass_id;
   float random_number = (float)ob->random_id * (1.0f / (float)0xFFFFFFFF);
   int particle_index = (ob->particle_system) ?
@@ -425,6 +427,9 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
   kobject.tfm = tfm;
   kobject.itfm = itfm;
   kobject.surface_area = surface_area;
+  kobject.color[0] = color.x;
+  kobject.color[1] = color.y;
+  kobject.color[2] = color.z;
   kobject.pass_id = pass_id;
   kobject.random_number = random_number;
   kobject.particle_index = particle_index;
index 2fd43900da14ae4eafc50c1e2efa5d43b6222341..cbbff0d4c6d3b642e80d9995471d9c9925133de1 100644 (file)
@@ -51,6 +51,7 @@ class Object : public Node {
   BoundBox bounds;
   uint random_id;
   int pass_id;
+  float3 color;
   ustring asset_name;
   vector<ParamValue> attributes;
   uint visibility;
index 72fcb9ac96839d9dd66facaf8475aa9f6f82b0cf..3d8a7bb1e30c1998b96f121ac150ee18e25b96c0 100644 (file)
@@ -603,6 +603,7 @@ static DRWCallState *draw_unit_state_create(void)
 
   state->ob_index = 0;
   state->ob_random = 0.0f;
+  copy_v3_fl(state->ob_color, 1.0f);
 
   /* TODO(fclem) get rid of this. */
   state->culling = BLI_memblock_alloc(DST.vmempool->cullstates);
index f37e713e374de0cdf32677d294225b70ba54159c..85f6cf05e834ea988cd90bfd4b5f48eb47bd1823 100644 (file)
@@ -101,6 +101,7 @@ enum {
   DRW_CALL_MODELVIEWPROJECTION = (1 << 1),
   DRW_CALL_ORCOTEXFAC = (1 << 2),
   DRW_CALL_OBJECTINFO = (1 << 3),
+  DRW_CALL_OBJECTCOLOR = (1 << 4),
 };
 
 typedef struct DRWCullingState {
@@ -122,6 +123,7 @@ typedef struct DRWCallState {
   float modelinverse[4][4];
   float orcotexfac[2][3];
   float ob_random;
+  float ob_color[4];
 } DRWCallState;
 
 typedef struct DRWCall {
@@ -196,6 +198,7 @@ struct DRWShadingGroup {
   int orcotexfac;
   int callid;
   int objectinfo;
+  int objectcolor;
   uchar matflag; /* Matrices needed, same as DRWCall.flag */
 
   DRWPass *pass_parent; /* backlink to pass we're in */
index 99ab25645d222c75e7c4eeafa438c03e87613841..8b7cb9c1dadf96c237c56cd85aabe5836e10ba3d 100644 (file)
@@ -387,6 +387,10 @@ static void drw_call_state_update_matflag(DRWCallState *state,
     }
     state->ob_random = random * (1.0f / (float)0xFFFFFFFF);
   }
+
+  if (new_flags & DRW_CALL_OBJECTCOLOR) {
+    copy_v4_v4(state->ob_color, ob->color);
+  }
 }
 
 static DRWCallState *drw_call_state_create(DRWShadingGroup *shgroup, float (*obmat)[4], Object *ob)
@@ -836,6 +840,7 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
   shgroup->modelviewprojection = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MVP);
   shgroup->orcotexfac = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_ORCO);
   shgroup->objectinfo = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_OBJECT_INFO);
+  shgroup->objectcolor = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_OBJECT_COLOR);
   shgroup->callid = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_CALLID);
 
   shgroup->matflag = 0;
@@ -851,6 +856,9 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
   if (shgroup->objectinfo > -1) {
     shgroup->matflag |= DRW_CALL_OBJECTINFO;
   }
+  if (shgroup->objectcolor > -1) {
+    shgroup->matflag |= DRW_CALL_OBJECTCOLOR;
+  }
 }
 
 static DRWShadingGroup *drw_shgroup_create_ex(struct GPUShader *shader, DRWPass *pass)
index 09bf12dba7b4999c1b7da1549273ec7574212dad..50408015fbc8cdb8ebe0be002b78ebca9361eac3 100644 (file)
@@ -592,6 +592,10 @@ static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCall *call)
     infos[3] = (state->flag & DRW_CALL_NEGSCALE) ? -1.0f : 1.0f;
     GPU_shader_uniform_vector(shgroup->shader, shgroup->objectinfo, 4, 1, (float *)infos);
   }
+  if (shgroup->objectcolor != -1) {
+    GPU_shader_uniform_vector(
+        shgroup->shader, shgroup->objectcolor, 4, 1, (float *)state->ob_color);
+  }
   if (shgroup->orcotexfac != -1) {
     GPU_shader_uniform_vector(
         shgroup->shader, shgroup->orcotexfac, 3, 2, (float *)state->orcotexfac);
index dd5292d9c580abd5d01a289fae86a2c741507f4e..2e0dc750e46a1321d9d77d49c9da8dcf23e72339 100644 (file)
@@ -92,7 +92,7 @@ typedef enum eGPUBuiltin {
   GPU_INVERSE_OBJECT_MATRIX = (1 << 3),
   GPU_VIEW_POSITION = (1 << 4),
   GPU_VIEW_NORMAL = (1 << 5),
-  GPU_OBCOLOR = (1 << 6),
+  GPU_OBJECT_COLOR = (1 << 6),
   GPU_AUTO_BUMPSCALE = (1 << 7),
   GPU_CAMERA_TEXCO_FACTORS = (1 << 8),
   GPU_PARTICLE_SCALAR_PROPS = (1 << 9),
index d3a9a18b392de2255a76ff28a35e144279ba22aa..ec97e1b085ea2878b7083848956a4d5f3f5c1ffb 100644 (file)
@@ -48,9 +48,10 @@ typedef enum {
   GPU_UNIFORM_ORCO,       /* vec3 OrcoTexCoFactors[] */
   GPU_UNIFORM_CLIPPLANES, /* vec4 WorldClipPlanes[] */
 
-  GPU_UNIFORM_COLOR,       /* vec4 color */
-  GPU_UNIFORM_CALLID,      /* int callId */
-  GPU_UNIFORM_OBJECT_INFO, /* vec3 objectInfo */
+  GPU_UNIFORM_COLOR,        /* vec4 color */
+  GPU_UNIFORM_CALLID,       /* int callId */
+  GPU_UNIFORM_OBJECT_INFO,  /* vec3 objectInfo */
+  GPU_UNIFORM_OBJECT_COLOR, /* vec4 objectColor */
 
   GPU_UNIFORM_CUSTOM, /* custom uniform, not one of the above built-ins */
 
index 0e15fdd000bb4e905cbe77860145430b4b4416e3..55337596cbefc9e4ec720042dfe750fde22cf1ee 100644 (file)
@@ -542,8 +542,8 @@ const char *GPU_builtin_name(eGPUBuiltin builtin)
   else if (builtin == GPU_VIEW_NORMAL) {
     return "varnormal";
   }
-  else if (builtin == GPU_OBCOLOR) {
-    return "unfobcolor";
+  else if (builtin == GPU_OBJECT_COLOR) {
+    return "unfobjectcolor";
   }
   else if (builtin == GPU_AUTO_BUMPSCALE) {
     return "unfobautobumpscale";
index e34c6e230249ee0440f60e4d3b29a9c7f5616def..f205ef31ed2053abc1e2380b02e16144e8e0da78 100644 (file)
@@ -67,6 +67,7 @@ static const char *BuiltinUniform_name(GPUUniformBuiltin u)
       [GPU_UNIFORM_COLOR] = "color",
       [GPU_UNIFORM_CALLID] = "callId",
       [GPU_UNIFORM_OBJECT_INFO] = "unfobjectinfo",
+      [GPU_UNIFORM_OBJECT_COLOR] = "unfobjectcolor",
 
       [GPU_UNIFORM_CUSTOM] = NULL,
       [GPU_NUM_UNIFORMS] = NULL,
index acd28789364f3314599e6b74128179c238cf2754..24fef4f05d895947e043cbfe2867f913c30c5f35 100644 (file)
@@ -3629,14 +3629,17 @@ void node_light_falloff(
 }
 
 void node_object_info(mat4 obmat,
+                      vec4 obcolor,
                       vec4 info,
                       float mat_index,
                       out vec3 location,
+                      out vec4 color,
                       out float object_index,
                       out float material_index,
                       out float random)
 {
   location = obmat[3].xyz;
+  color = obcolor;
   object_index = info.x;
   material_index = mat_index;
   random = info.z;
index 1c83e91db9db1e39fc58658c21750de4084ee9f6..0a4016f3d4a0d30045a2414f513bb9b08aed61e8 100644 (file)
@@ -2851,7 +2851,7 @@ static void rna_def_object(BlenderRNA *brna)
   prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
   RNA_def_property_ui_text(
       prop, "Color", "Object color and alpha, used when faces have the ObColor mode enabled");
-  RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+  RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update_draw");
 
   /* physics */
   prop = RNA_def_property(srna, "field", PROP_POINTER, PROP_NONE);
index 118b8136693fcfdf1eb07b8f9903371f983b453e..58449a53706fe04f8ad353c6b6198a106229c313 100644 (file)
@@ -23,6 +23,7 @@
 
 static bNodeSocketTemplate sh_node_object_info_out[] = {
     {SOCK_VECTOR, 0, N_("Location"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+    {SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
     {SOCK_FLOAT, 0, N_("Object Index"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
     {SOCK_FLOAT, 0, N_("Material Index"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
     {SOCK_FLOAT, 0, N_("Random"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
@@ -36,38 +37,25 @@ static int node_shader_gpu_object_info(GPUMaterial *mat,
                                        GPUNodeStack *out)
 {
   Material *ma = GPU_material_get_material(mat);
-  /* Convert to float. */
-  float index = ma ? ma->index : 0;
+  float index = ma ? ma->index : 0.0f;
   return GPU_stack_link(mat,
                         node,
                         "node_object_info",
                         in,
                         out,
                         GPU_builtin(GPU_OBJECT_MATRIX),
+                        GPU_builtin(GPU_OBJECT_COLOR),
                         GPU_builtin(GPU_OBJECT_INFO),
                         GPU_constant(&index));
 }
 
-static void node_shader_exec_object_info(void *UNUSED(data),
-                                         int UNUSED(thread),
-                                         bNode *UNUSED(node),
-                                         bNodeExecData *UNUSED(execdata),
-                                         bNodeStack **UNUSED(in),
-                                         bNodeStack **UNUSED(out))
-{
-}
-
-/* node type definition */
 void register_node_type_sh_object_info(void)
 {
   static bNodeType ntype;
 
   sh_node_type_base(&ntype, SH_NODE_OBJECT_INFO, "Object Info", NODE_CLASS_INPUT, 0);
   node_type_socket_templates(&ntype, NULL, sh_node_object_info_out);
-  node_type_init(&ntype, NULL);
-  node_type_storage(&ntype, "", NULL, NULL);
   node_type_gpu(&ntype, node_shader_gpu_object_info);
-  node_type_exec(&ntype, NULL, NULL, node_shader_exec_object_info);
 
   nodeRegisterType(&ntype);
 }