diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-05-21 16:52:28 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-05-21 16:52:28 +0400 |
commit | c3e1fce77552b5626d2939710cb6d0020891d218 (patch) | |
tree | 5d59df38ec009f21000a959531129aa511868773 /intern/cycles/render | |
parent | ea11bc980ad428950efb430618a6de439ffd5951 (diff) |
Cycles: add Object Info node, with outputs object location, object/material
pass index, and a random number unique to the instance of the object.
This can be useful to give some variation to a single material assigned to
multiple instances, either manually controlled through the object index, based
on the object location, or randomized for each instance.
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/More#Object_Info
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/nodes.cpp | 45 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 5 | ||||
-rw-r--r-- | intern/cycles/render/object.cpp | 7 | ||||
-rw-r--r-- | intern/cycles/render/object.h | 1 |
4 files changed, 56 insertions, 2 deletions
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 57fe2fb01b7..506458d82e1 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1699,7 +1699,7 @@ void LightPathNode::compile(OSLCompiler& compiler) compiler.add(this, "node_light_path"); } -/* Light Path */ +/* Light Falloff */ LightFalloffNode::LightFalloffNode() : ShaderNode("light_path") @@ -1746,6 +1746,49 @@ void LightFalloffNode::compile(OSLCompiler& compiler) compiler.add(this, "node_light_falloff"); } +/* Object Info */ + +ObjectInfoNode::ObjectInfoNode() +: ShaderNode("object_info") +{ + add_output("Location", SHADER_SOCKET_VECTOR); + add_output("Object Index", SHADER_SOCKET_FLOAT); + add_output("Material Index", SHADER_SOCKET_FLOAT); + add_output("Random", SHADER_SOCKET_FLOAT); +} + +void ObjectInfoNode::compile(SVMCompiler& compiler) +{ + ShaderOutput *out = output("Location"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_LOCATION, out->stack_offset); + } + + out = output("Object Index"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_INDEX, out->stack_offset); + } + + out = output("Material Index"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_MAT_INDEX, out->stack_offset); + } + + out = output("Random"); + if(!out->links.empty()) { + compiler.stack_assign(out); + compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_RANDOM, out->stack_offset); + } +} + +void ObjectInfoNode::compile(OSLCompiler& compiler) +{ + compiler.add(this, "node_object_info"); +} + /* Value */ ValueNode::ValueNode() diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index ff9e3647d01..2d0d58d1e94 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -285,6 +285,11 @@ public: SHADER_NODE_CLASS(LightFalloffNode) }; +class ObjectInfoNode : public ShaderNode { +public: + SHADER_NODE_CLASS(ObjectInfoNode) +}; + class ValueNode : public ShaderNode { public: SHADER_NODE_CLASS(ValueNode) diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index cae69c06f7d..e38b2635f90 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -23,6 +23,7 @@ #include "scene.h" #include "util_foreach.h" +#include "util_hash.h" #include "util_map.h" #include "util_progress.h" @@ -36,6 +37,7 @@ Object::Object() mesh = NULL; tfm = transform_identity(); visibility = ~0; + instance_id = 0; pass_id = 0; bounds = BoundBox::empty; motion.pre = transform_identity(); @@ -164,6 +166,9 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene float surface_area = 0.0f; float pass_id = ob->pass_id; + uint ob_hash = hash_int_2d(hash_string(ob->name.c_str()), ob->instance_id); + float random_number = (float)ob_hash * (1.0f/(float)0xFFFFFFFF); + if(transform_uniform_scale(tfm, uniform_scale)) { map<Mesh*, float>::iterator it = surface_area_map.find(mesh); @@ -198,7 +203,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene memcpy(&objects[offset], &tfm, sizeof(float4)*3); memcpy(&objects[offset+3], &itfm, sizeof(float4)*3); - objects[offset+6] = make_float4(surface_area, pass_id, 0.0f, 0.0f); + objects[offset+6] = make_float4(surface_area, pass_id, random_number, 0.0f); if(need_motion == Scene::MOTION_PASS) { /* motion transformations, is world/object space depending if mesh diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 267052bfca7..b8169e3758e 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -41,6 +41,7 @@ public: Transform tfm; BoundBox bounds; ustring name; + int instance_id; int pass_id; vector<ParamValue> attributes; uint visibility; |