diff options
author | OmarSquircleArt <omar.squircleart@gmail.com> | 2019-08-22 15:26:09 +0300 |
---|---|---|
committer | OmarSquircleArt <omar.squircleart@gmail.com> | 2019-08-22 15:26:09 +0300 |
commit | 08ab3cbcce1eb9c2de4953a83b50cabc44479d3c (patch) | |
tree | ef169595562509b0e3338cecb36a3b3210bd64ce | |
parent | a2443848646cdb5d13980157a8c62eb4cd578388 (diff) |
Shading: Add object color to Object Info node.
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, 69 insertions, 24 deletions
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index ab47da9c1a2..b670922ac88 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -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(); diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h index f410e6e27e2..af4e6fbd89b 100644 --- a/intern/cycles/kernel/geom/geom_object.h +++ b/intern/cycles/kernel/geom/geom_object.h @@ -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) diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index f3f321e77dc..8aaa83045ea 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -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); diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 3850d0fe94b..222475b3778 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -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); diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index 024ef656be1..469c5188730 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -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; diff --git a/intern/cycles/kernel/shaders/node_object_info.osl b/intern/cycles/kernel/shaders/node_object_info.osl index 0904a30a53f..350404bb747 100644 --- a/intern/cycles/kernel/shaders/node_object_info.osl +++ b/intern/cycles/kernel/shaders/node_object_info.osl @@ -17,11 +17,13 @@ #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); diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 4abe0831858..019c6294082 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -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; diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 6f412074125..a3caa1ab68d 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -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 diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 3a5d65039c8..69c1c06f846 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -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)); diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 6c6f8810412..849329a086d 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -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; diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 2fd43900da1..cbbff0d4c6d 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -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; diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 72fcb9ac968..3d8a7bb1e30 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -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); diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index f37e713e374..85f6cf05e83 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -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 */ diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 99ab25645d2..8b7cb9c1dad 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -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) diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 09bf12dba7b..50408015fbc 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -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); diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index dd5292d9c58..2e0dc750e46 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -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), diff --git a/source/blender/gpu/GPU_shader_interface.h b/source/blender/gpu/GPU_shader_interface.h index d3a9a18b392..ec97e1b085e 100644 --- a/source/blender/gpu/GPU_shader_interface.h +++ b/source/blender/gpu/GPU_shader_interface.h @@ -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 */ diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 0e15fdd000b..55337596cbe 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -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"; diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.c index e34c6e23024..f205ef31ed2 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.c +++ b/source/blender/gpu/intern/gpu_shader_interface.c @@ -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, diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index acd28789364..24fef4f05d8 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -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; diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 1c83e91db9d..0a4016f3d4a 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -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); diff --git a/source/blender/nodes/shader/nodes/node_shader_object_info.c b/source/blender/nodes/shader/nodes/node_shader_object_info.c index 118b8136693..58449a53706 100644 --- a/source/blender/nodes/shader/nodes/node_shader_object_info.c +++ b/source/blender/nodes/shader/nodes/node_shader_object_info.c @@ -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); } |