Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-05-21 16:52:28 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-05-21 16:52:28 +0400
commitc3e1fce77552b5626d2939710cb6d0020891d218 (patch)
tree5d59df38ec009f21000a959531129aa511868773 /intern
parentea11bc980ad428950efb430618a6de439ffd5951 (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')
-rw-r--r--intern/cycles/blender/blender_object.cpp1
-rw-r--r--intern/cycles/blender/blender_shader.cpp4
-rw-r--r--intern/cycles/kernel/kernel_object.h25
-rw-r--r--intern/cycles/kernel/kernel_shader.h5
-rw-r--r--intern/cycles/kernel/svm/svm.h3
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h20
-rw-r--r--intern/cycles/kernel/svm/svm_types.h10
-rw-r--r--intern/cycles/render/nodes.cpp45
-rw-r--r--intern/cycles/render/nodes.h5
-rw-r--r--intern/cycles/render/object.cpp7
-rw-r--r--intern/cycles/render/object.h1
-rw-r--r--intern/cycles/util/util_hash.h18
12 files changed, 133 insertions, 11 deletions
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 641aa88d6ef..405c7eada1d 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -245,6 +245,7 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob,
/* 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;
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index b33de789631..59eeb25ed74 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -334,6 +334,10 @@ static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Shader
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());
diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h
index abe427d8345..05c45c490d8 100644
--- a/intern/cycles/kernel/kernel_object.h
+++ b/intern/cycles/kernel/kernel_object.h
@@ -117,6 +117,16 @@ __device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, flo
#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 @@ __device_inline float object_pass_id(KernelGlobals *kg, int object)
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
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 2138038e49d..8e0d36705ad 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -679,11 +679,6 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
}
#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)
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 12ed61673d1..6a05639beb9 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -266,6 +266,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
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);
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index 77fe26c809e..dab19983946 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -74,5 +74,25 @@ __device void svm_node_geometry_bump_dy(ShaderData *sd, float *stack, uint type,
#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
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 867709f29e0..97849736ef6 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -92,7 +92,8 @@ typedef enum NodeType {
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 @@ typedef enum NodeGeometry {
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,
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;
diff --git a/intern/cycles/util/util_hash.h b/intern/cycles/util/util_hash.h
index 16901dab38e..c31b46e1580 100644
--- a/intern/cycles/util/util_hash.h
+++ b/intern/cycles/util/util_hash.h
@@ -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 @@ static inline unsigned int hash_int_2d(unsigned int kx, unsigned int ky)
#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__ */