Revision: 46841 http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46841 Author: blendix Date: 2012-05-21 12:52:28 +0000 (Mon, 21 May 2012) Log Message: ----------- 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 Modified Paths: -------------- trunk/blender/intern/cycles/blender/blender_object.cpp trunk/blender/intern/cycles/blender/blender_shader.cpp trunk/blender/intern/cycles/kernel/kernel_object.h trunk/blender/intern/cycles/kernel/kernel_shader.h trunk/blender/intern/cycles/kernel/svm/svm.h trunk/blender/intern/cycles/kernel/svm/svm_geometry.h trunk/blender/intern/cycles/kernel/svm/svm_types.h trunk/blender/intern/cycles/render/nodes.cpp trunk/blender/intern/cycles/render/nodes.h trunk/blender/intern/cycles/render/object.cpp trunk/blender/intern/cycles/render/object.h trunk/blender/intern/cycles/util/util_hash.h trunk/blender/source/blender/blenkernel/BKE_node.h trunk/blender/source/blender/blenkernel/intern/node.c trunk/blender/source/blender/gpu/shaders/gpu_shader_material.glsl trunk/blender/source/blender/gpu/shaders/gpu_shader_material.glsl.c trunk/blender/source/blender/makesrna/intern/rna_nodetree_types.h trunk/blender/source/blender/nodes/CMakeLists.txt trunk/blender/source/blender/nodes/NOD_shader.h Added Paths: ----------- trunk/blender/source/blender/nodes/shader/nodes/node_shader_object_info.c Modified: trunk/blender/intern/cycles/blender/blender_object.cpp =================================================================== --- trunk/blender/intern/cycles/blender/blender_object.cpp 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/blender/blender_object.cpp 2012-05-21 12:52:28 UTC (rev 46841) @@ -245,6 +245,7 @@ /* object sync */ if(object_updated || (object->mesh && object->mesh->need_update)) { object->name = b_ob.name().c_str(); + object->instance_id = b_index; object->pass_id = b_ob.pass_index(); object->tfm = tfm; object->motion.pre = tfm; Modified: trunk/blender/intern/cycles/blender/blender_shader.cpp =================================================================== --- trunk/blender/intern/cycles/blender/blender_shader.cpp 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/blender/blender_shader.cpp 2012-05-21 12:52:28 UTC (rev 46841) @@ -334,6 +334,10 @@ node = new LightFalloffNode(); break; } + case BL::ShaderNode::type_OBJECT_INFO: { + node = new ObjectInfoNode(); + break; + } case BL::ShaderNode::type_TEX_IMAGE: { BL::ShaderNodeTexImage b_image_node(b_node); BL::Image b_image(b_image_node.image()); Modified: trunk/blender/intern/cycles/kernel/kernel_object.h =================================================================== --- trunk/blender/intern/cycles/kernel/kernel_object.h 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/kernel/kernel_object.h 2012-05-21 12:52:28 UTC (rev 46841) @@ -117,6 +117,16 @@ #endif } +__device_inline float3 object_location(KernelGlobals *kg, ShaderData *sd) +{ +#ifdef __MOTION__ + return make_float3(sd->ob_tfm.x.w, sd->ob_tfm.y.w, sd->ob_tfm.z.w); +#else + Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM); + return make_float3(tfm.x.w, tfm.y.w, tfm.z.w); +#endif +} + __device_inline float object_surface_area(KernelGlobals *kg, int object) { int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; @@ -134,5 +144,20 @@ return f.y; } +__device_inline float object_random_number(KernelGlobals *kg, int object) +{ + if(object == ~0) + return 0.0f; + + int offset = object*OBJECT_SIZE + OBJECT_PROPERTIES; + float4 f = kernel_tex_fetch(__objects, offset); + return f.z; +} + +__device int shader_pass_id(KernelGlobals *kg, ShaderData *sd) +{ + return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1); +} + CCL_NAMESPACE_END Modified: trunk/blender/intern/cycles/kernel/kernel_shader.h =================================================================== --- trunk/blender/intern/cycles/kernel/kernel_shader.h 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/kernel/kernel_shader.h 2012-05-21 12:52:28 UTC (rev 46841) @@ -679,11 +679,6 @@ } #endif -__device int shader_pass_id(KernelGlobals *kg, ShaderData *sd) -{ - return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1); -} - /* Free ShaderData */ __device void shader_release(KernelGlobals *kg, ShaderData *sd) Modified: trunk/blender/intern/cycles/kernel/svm/svm.h =================================================================== --- trunk/blender/intern/cycles/kernel/svm/svm.h 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/kernel/svm/svm.h 2012-05-21 12:52:28 UTC (rev 46841) @@ -266,6 +266,9 @@ case NODE_LIGHT_PATH: svm_node_light_path(sd, stack, node.y, node.z, path_flag); break; + case NODE_OBJECT_INFO: + svm_node_object_info(kg, sd, stack, node.y, node.z); + break; #endif case NODE_CONVERT: svm_node_convert(sd, stack, node.y, node.z, node.w); Modified: trunk/blender/intern/cycles/kernel/svm/svm_geometry.h =================================================================== --- trunk/blender/intern/cycles/kernel/svm/svm_geometry.h 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/kernel/svm/svm_geometry.h 2012-05-21 12:52:28 UTC (rev 46841) @@ -74,5 +74,25 @@ #endif } +/* Object Info */ + +__device void svm_node_object_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) +{ + float data; + + switch(type) { + case NODE_INFO_OB_LOCATION: { + stack_store_float3(stack, out_offset, object_location(kg, sd)); + return; + } + case NODE_INFO_OB_INDEX: data = object_pass_id(kg, sd->object); break; + case NODE_INFO_MAT_INDEX: data = shader_pass_id(kg, sd); break; + case NODE_INFO_OB_RANDOM: data = object_random_number(kg, sd->object); break; + default: data = 0.0f; break; + } + + stack_store_float(stack, out_offset, data); +} + CCL_NAMESPACE_END Modified: trunk/blender/intern/cycles/kernel/svm/svm_types.h =================================================================== --- trunk/blender/intern/cycles/kernel/svm/svm_types.h 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/kernel/svm/svm_types.h 2012-05-21 12:52:28 UTC (rev 46841) @@ -92,7 +92,8 @@ NODE_RGB_RAMP = 5900, NODE_RGB_CURVES = 6000, NODE_MIN_MAX = 6100, - NODE_LIGHT_FALLOFF = 6200 + NODE_LIGHT_FALLOFF = 6200, + NODE_OBJECT_INFO = 6300 } NodeType; typedef enum NodeAttributeType { @@ -109,6 +110,13 @@ NODE_GEOM_uv } NodeGeometry; +typedef enum NodeObjectInfo { + NODE_INFO_OB_LOCATION, + NODE_INFO_OB_INDEX, + NODE_INFO_MAT_INDEX, + NODE_INFO_OB_RANDOM +} NodeObjectInfo; + typedef enum NodeLightPath { NODE_LP_camera = 0, NODE_LP_shadow, Modified: trunk/blender/intern/cycles/render/nodes.cpp =================================================================== --- trunk/blender/intern/cycles/render/nodes.cpp 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/render/nodes.cpp 2012-05-21 12:52:28 UTC (rev 46841) @@ -1699,7 +1699,7 @@ compiler.add(this, "node_light_path"); } -/* Light Path */ +/* Light Falloff */ LightFalloffNode::LightFalloffNode() : ShaderNode("light_path") @@ -1746,6 +1746,49 @@ 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() Modified: trunk/blender/intern/cycles/render/nodes.h =================================================================== --- trunk/blender/intern/cycles/render/nodes.h 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/render/nodes.h 2012-05-21 12:52:28 UTC (rev 46841) @@ -285,6 +285,11 @@ SHADER_NODE_CLASS(LightFalloffNode) }; +class ObjectInfoNode : public ShaderNode { +public: + SHADER_NODE_CLASS(ObjectInfoNode) +}; + class ValueNode : public ShaderNode { public: SHADER_NODE_CLASS(ValueNode) Modified: trunk/blender/intern/cycles/render/object.cpp =================================================================== --- trunk/blender/intern/cycles/render/object.cpp 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/render/object.cpp 2012-05-21 12:52:28 UTC (rev 46841) @@ -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 @@ mesh = NULL; tfm = transform_identity(); visibility = ~0; + instance_id = 0; pass_id = 0; bounds = BoundBox::empty; motion.pre = transform_identity(); @@ -164,6 +166,9 @@ 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 @@ 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 Modified: trunk/blender/intern/cycles/render/object.h =================================================================== --- trunk/blender/intern/cycles/render/object.h 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/render/object.h 2012-05-21 12:52:28 UTC (rev 46841) @@ -41,6 +41,7 @@ Transform tfm; BoundBox bounds; ustring name; + int instance_id; int pass_id; vector<ParamValue> attributes; uint visibility; Modified: trunk/blender/intern/cycles/util/util_hash.h =================================================================== --- trunk/blender/intern/cycles/util/util_hash.h 2012-05-21 12:30:06 UTC (rev 46840) +++ trunk/blender/intern/cycles/util/util_hash.h 2012-05-21 12:52:28 UTC (rev 46841) @@ -19,13 +19,15 @@ #ifndef __UTIL_HASH_H__ #define __UTIL_HASH_H__ +#include "util_types.h" + CCL_NAMESPACE_BEGIN -static inline unsigned int hash_int_2d(unsigned int kx, unsigned int ky) +static inline uint hash_int_2d(uint kx, uint ky) { #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) - unsigned int a, b, c; + uint a, b, c; a = b = c = 0xdeadbeef + (2 << 2) + 13; a += kx; @@ -44,11 +46,21 @@ #undef rot } -static inline unsigned int hash_int(unsigned int k) +static inline uint hash_int(uint k) { return hash_int_2d(k, 0); } +static inline uint hash_string(const char *str) +{ + uint i = 0, c; + + while ((c = *str++)) + i = i * 37 + c; + + return i; +} + CCL_NAMESPACE_END #endif /* __UTIL_HASH_H__ */ @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs