[Bf-blender-cvs] [212a8d9e5ae] master: Cycles: Make per-object random value output also work for Lamps

Lukas Stockner noreply at git.blender.org
Tue Nov 14 05:12:11 CET 2017


Commit: 212a8d9e5ae78a30ed4c35161d91eeca35eaa41f
Author: Lukas Stockner
Date:   Sun Nov 5 21:59:17 2017 +0100
Branches: master
https://developer.blender.org/rB212a8d9e5ae78a30ed4c35161d91eeca35eaa41f

Cycles: Make per-object random value output also work for Lamps

===================================================================

M	intern/cycles/blender/blender_object.cpp
M	intern/cycles/blender/blender_sync.h
M	intern/cycles/kernel/geom/geom_object.h
M	intern/cycles/kernel/kernel_shader.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/kernel/svm/svm_geometry.h
M	intern/cycles/render/light.cpp
M	intern/cycles/render/light.h

===================================================================

diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index eb573b75e9e..f02d5496112 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -112,6 +112,7 @@ static uint object_ray_visibility(BL::Object& b_ob)
 void BlenderSync::sync_light(BL::Object& b_parent,
                              int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
                              BL::Object& b_ob,
+                             BL::DupliObject& b_dupli_ob,
                              Transform& tfm,
                              bool *use_portal)
 {
@@ -193,6 +194,13 @@ void BlenderSync::sync_light(BL::Object& b_parent,
 
 	light->max_bounces = get_int(clamp, "max_bounces");
 
+	if(b_dupli_ob) {
+		light->random_id = b_dupli_ob.random_id();
+	}
+	else {
+		light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0);
+	}
+
 	if(light->type == LIGHT_AREA)
 		light->is_portal = get_boolean(clamp, "is_portal");
 	else
@@ -271,7 +279,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
 	if(object_is_light(b_ob)) {
 		/* don't use lamps for excluded layers used as mask layer */
 		if(!motion && !((layer_flag & render_layer.holdout_layer) && (layer_flag & render_layer.exclude_layer)))
-			sync_light(b_parent, persistent_id, b_ob, tfm, use_portal);
+			sync_light(b_parent, persistent_id, b_ob, b_dupli_ob, tfm, use_portal);
 
 		return NULL;
 	}
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 11e279b81c4..e7b71ae9310 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -131,6 +131,7 @@ private:
 	void sync_light(BL::Object& b_parent,
 	                int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
 	                BL::Object& b_ob,
+	                BL::DupliObject& b_dupli_ob,
 	                Transform& tfm,
 	                bool *use_portal);
 	void sync_background_light(bool use_portal);
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h
index 1ffc143be34..a276096a745 100644
--- a/intern/cycles/kernel/geom/geom_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -244,6 +244,17 @@ ccl_device_inline float object_pass_id(KernelGlobals *kg, int object)
 	return f.y;
 }
 
+/* Per lamp random number for shader variation */
+
+ccl_device_inline float lamp_random_number(KernelGlobals *kg, int lamp)
+{
+	if(lamp == LAMP_NONE)
+		return 0.0f;
+
+	float4 f = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 4);
+	return f.y;
+}
+
 /* Per object random number for shader variation */
 
 ccl_device_inline float object_random_number(KernelGlobals *kg, int object)
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 239c6b12bdf..26d3fcf15b2 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -57,6 +57,7 @@ ccl_device_noinline void shader_setup_from_ray(KernelGlobals *kg,
 #ifdef __INSTANCING__
 	sd->object = (isect->object == PRIM_NONE)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
 #endif
+	sd->lamp = LAMP_NONE;
 
 	sd->type = isect->type;
 	sd->flag = 0;
@@ -265,6 +266,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg,
 #ifdef __INSTANCING__
 	sd->object = object;
 #endif
+	sd->lamp = LAMP_NONE;
 	/* currently no access to bvh prim index for strand sd->prim*/
 	sd->prim = prim;
 #ifdef __UV__
@@ -286,6 +288,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg,
 	else if(lamp != LAMP_NONE) {
 		sd->ob_tfm  = lamp_fetch_transform(kg, lamp, false);
 		sd->ob_itfm = lamp_fetch_transform(kg, lamp, true);
+		sd->lamp = lamp;
 #endif
 	}
 
@@ -391,6 +394,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
 #ifdef __INSTANCING__
 	sd->object = PRIM_NONE;
 #endif
+	sd->lamp = LAMP_NONE;
 	sd->prim = PRIM_NONE;
 #ifdef __UV__
 	sd->u = 0.0f;
@@ -431,6 +435,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *s
 #  ifdef __INSTANCING__
 	sd->object = PRIM_NONE; /* todo: fill this for texture coordinates */
 #  endif
+	sd->lamp = LAMP_NONE;
 	sd->prim = PRIM_NONE;
 	sd->type = PRIMITIVE_NONE;
 
@@ -1143,6 +1148,7 @@ ccl_device_inline void shader_eval_volume(KernelGlobals *kg,
 		/* setup shaderdata from stack. it's mostly setup already in
 		 * shader_setup_from_volume, this switching should be quick */
 		sd->object = stack[i].object;
+		sd->lamp = LAMP_NONE;
 		sd->shader = stack[i].shader;
 
 		sd->flag &= ~SD_SHADER_FLAGS;
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 919dafbc780..5b8b760c48c 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -957,6 +957,8 @@ typedef ccl_addr_space struct ShaderData {
 	float v;
 	/* object id if there is one, ~0 otherwise */
 	int object;
+	/* lamp id if there is one, ~0 otherwise */
+	int lamp;
 
 	/* motion blur sample time */
 	float time;
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index cce4e89e715..9af4a0182d9 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -90,7 +90,15 @@ ccl_device void svm_node_object_info(KernelGlobals *kg, ShaderData *sd, float *s
 		}
 		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;
+		case NODE_INFO_OB_RANDOM: {
+			if(sd->lamp != LAMP_NONE) {
+				data = lamp_random_number(kg, sd->lamp);
+			}
+			else {
+				data = object_random_number(kg, sd->object);
+			}
+			break;
+		}
 		default: data = 0.0f; break;
 	}
 
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index b37a0768b53..b62453cf5fc 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -134,6 +134,7 @@ NODE_DEFINE(Light)
 
 	SOCKET_INT(samples, "Samples", 1);
 	SOCKET_INT(max_bounces, "Max Bounces", 1024);
+	SOCKET_UINT(random_id, "Random ID", 0);
 
 	SOCKET_BOOLEAN(is_portal, "Is Portal", false);
 	SOCKET_BOOLEAN(is_enabled, "Is Enabled", true);
@@ -638,6 +639,7 @@ void LightManager::device_update_points(Device *,
 		int shader_id = scene->shader_manager->get_shader_id(shader);
 		float samples = __int_as_float(light->samples);
 		float max_bounces = __int_as_float(light->max_bounces);
+		float random = (float)light->random_id * (1.0f/(float)0xFFFFFFFF);
 
 		if(!light->cast_shadow)
 			shader_id &= ~SHADER_CAST_SHADOW;
@@ -758,7 +760,7 @@ void LightManager::device_update_points(Device *,
 			light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
 		}
 
-		light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f);
+		light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, random, 0.0f, 0.0f);
 
 		Transform tfm = light->tfm;
 		Transform itfm = transform_inverse(tfm);
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index 7e9014eb823..97b7b971c73 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -70,6 +70,7 @@ public:
 	Shader *shader;
 	int samples;
 	int max_bounces;
+	uint random_id;
 
 	void tag_update(Scene *scene);



More information about the Bf-blender-cvs mailing list