[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [47426] trunk/blender/intern/cycles: Cycles: spot lamp support.

Brecht Van Lommel brechtvanlommel at pandora.be
Mon Jun 4 19:17:12 CEST 2012


Revision: 47426
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=47426
Author:   blendix
Date:     2012-06-04 17:17:10 +0000 (Mon, 04 Jun 2012)
Log Message:
-----------
Cycles: spot lamp support.

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/addon/ui.py
    trunk/blender/intern/cycles/blender/blender_object.cpp
    trunk/blender/intern/cycles/kernel/kernel_emission.h
    trunk/blender/intern/cycles/kernel/kernel_light.h
    trunk/blender/intern/cycles/kernel/kernel_types.h
    trunk/blender/intern/cycles/kernel/svm/emissive.h
    trunk/blender/intern/cycles/render/light.cpp
    trunk/blender/intern/cycles/render/light.h
    trunk/blender/intern/cycles/util/util_math.h

Modified: trunk/blender/intern/cycles/blender/addon/ui.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/ui.py	2012-06-04 17:13:38 UTC (rev 47425)
+++ trunk/blender/intern/cycles/blender/addon/ui.py	2012-06-04 17:17:10 UTC (rev 47426)
@@ -488,9 +488,7 @@
         col = split.column()
         col.prop(clamp, "cast_shadow")
 
-        if lamp.type == 'SPOT':
-            layout.label(text="Not supported, interpreted as point lamp.")
-        elif lamp.type == 'HEMI':
+        if lamp.type == 'HEMI':
             layout.label(text="Not supported, interpreted as sun lamp.")
 
 
@@ -509,7 +507,30 @@
         if not panel_node_draw(layout, lamp, 'OUTPUT_LAMP', 'Surface'):
             layout.prop(lamp, "color")
 
+class CyclesLamp_PT_spot(CyclesButtonsPanel, Panel):
+    bl_label = "Spot Shape"
+    bl_context = "data"
 
+    @classmethod
+    def poll(cls, context):
+        lamp = context.lamp
+        return (lamp and lamp.type == 'SPOT') and CyclesButtonsPanel.poll(context)
+
+    def draw(self, context):
+        layout = self.layout
+
+        lamp = context.lamp
+
+        split = layout.split()
+
+        col = split.column()
+        sub = col.column()
+        sub.prop(lamp, "spot_size", text="Size")
+        sub.prop(lamp, "spot_blend", text="Blend", slider=True)
+
+        col = split.column()
+        col.prop(lamp, "show_cone")
+
 class CyclesWorld_PT_surface(CyclesButtonsPanel, Panel):
     bl_label = "Surface"
     bl_context = "world"

Modified: trunk/blender/intern/cycles/blender/blender_object.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_object.cpp	2012-06-04 17:13:38 UTC (rev 47425)
+++ trunk/blender/intern/cycles/blender/blender_object.cpp	2012-06-04 17:17:10 UTC (rev 47426)
@@ -106,7 +106,9 @@
 		case BL::Lamp::type_SPOT: {
 			BL::SpotLamp b_spot_lamp(b_lamp);
 			light->size = b_spot_lamp.shadow_soft_size();
-			light->type = LIGHT_POINT;
+			light->type = LIGHT_SPOT;
+			light->spot_angle = b_spot_lamp.spot_size();
+			light->spot_smooth = b_spot_lamp.spot_blend();
 			break;
 		}
 		case BL::Lamp::type_HEMI: {

Modified: trunk/blender/intern/cycles/kernel/kernel_emission.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_emission.h	2012-06-04 17:13:38 UTC (rev 47425)
+++ trunk/blender/intern/cycles/kernel/kernel_emission.h	2012-06-04 17:17:10 UTC (rev 47426)
@@ -104,13 +104,8 @@
 		float mis_weight = power_heuristic(pdf, bsdf_pdf);
 		light_eval *= mis_weight;
 	}
-	/* todo: clean up these weights */
-	else if(ls.shader & SHADER_AREA_LIGHT)
-		light_eval *= 0.25f; /* area lamp */
-	else if(ls.t != FLT_MAX)
-		light_eval *= 0.25f*M_1_PI_F; /* point lamp */
 	
-	bsdf_eval_mul(eval, light_eval/pdf);
+	bsdf_eval_mul(eval, light_eval*(ls.eval_fac/pdf));
 
 	if(bsdf_eval_is_zero(eval))
 		return false;

Modified: trunk/blender/intern/cycles/kernel/kernel_light.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_light.h	2012-06-04 17:13:38 UTC (rev 47425)
+++ trunk/blender/intern/cycles/kernel/kernel_light.h	2012-06-04 17:17:10 UTC (rev 47426)
@@ -23,6 +23,7 @@
 	float3 D;
 	float3 Ng;
 	float t;
+	float eval_fac;
 	int object;
 	int prim;
 	int shader;
@@ -189,6 +190,7 @@
 		ls->Ng = D;
 		ls->D = -D;
 		ls->t = FLT_MAX;
+		ls->eval_fac = 1.0f;
 	}
 #ifdef __BACKGROUND_MIS__
 	else if(type == LIGHT_BACKGROUND) {
@@ -199,6 +201,7 @@
 		ls->Ng = D;
 		ls->D = -D;
 		ls->t = FLT_MAX;
+		ls->eval_fac = 1.0f;
 	}
 #endif
 	else {
@@ -212,7 +215,37 @@
 				ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
 
 			ls->Ng = normalize(P - ls->P);
+			ls->eval_fac = 0.25f*M_1_PI_F;
 		}
+		else if(type == LIGHT_SPOT) {
+			float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2);
+			float size = data1.y;
+
+			/* spot light */
+			if(size > 0.0f)
+				ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
+
+			float3 dir = make_float3(data1.z, data1.w, data2.x);
+			float3 I = normalize(P - ls->P);
+
+			float spot_angle = data2.y;
+			float spot_smooth = data2.z;
+
+			float eval_fac = fabsf(dot(dir, I));
+
+			if(eval_fac <= spot_angle) {
+				eval_fac = 0.0f;
+			}
+			else {
+				float t = eval_fac - spot_angle;
+
+				if(t < spot_smooth && spot_smooth != 0.0f)
+					eval_fac *= smoothstepf(t/spot_smooth);
+			}
+
+			ls->Ng = I;
+			ls->eval_fac = eval_fac*0.25f*M_1_PI_F;
+		}
 		else {
 			/* area light */
 			float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2);
@@ -224,6 +257,7 @@
 
 			ls->P += area_light_sample(axisu, axisv, randu, randv);
 			ls->Ng = D;
+			ls->eval_fac = 0.25f;
 		}
 
 		ls->t = 0.0f;
@@ -262,6 +296,7 @@
 	ls->prim = prim;
 	ls->t = 0.0f;
 	ls->type = LIGHT_AREA;
+	ls->eval_fac = 1.0f;
 
 #ifdef __INSTANCING__
 	/* instance transform */

Modified: trunk/blender/intern/cycles/kernel/kernel_types.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_types.h	2012-06-04 17:13:38 UTC (rev 47425)
+++ trunk/blender/intern/cycles/kernel/kernel_types.h	2012-06-04 17:17:10 UTC (rev 47426)
@@ -283,7 +283,8 @@
 	LIGHT_DISTANT,
 	LIGHT_BACKGROUND,
 	LIGHT_AREA,
-	LIGHT_AO
+	LIGHT_AO,
+	LIGHT_SPOT
 } LightType;
 
 /* Camera Type */

Modified: trunk/blender/intern/cycles/kernel/svm/emissive.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/emissive.h	2012-06-04 17:13:38 UTC (rev 47425)
+++ trunk/blender/intern/cycles/kernel/svm/emissive.h	2012-06-04 17:17:10 UTC (rev 47426)
@@ -34,14 +34,6 @@
 
 /* EMISSION CLOSURE */
 
-__device float3 emissive_eval(const float3 Ng, const float3 I)
-{
-	float cosNO = fabsf(dot(Ng, I));
-	float res = (cosNO > 0.0f)? 1.0f: 0.0f;
-	
-	return make_float3(res, res, res);
-}
-
 /// Return the probability distribution function in the direction I,
 /// given the parameters and the light's surface normal.  This MUST match
 /// the PDF computed by sample().
@@ -51,6 +43,13 @@
 	return (cosNO > 0.0f)? 1.0f: 0.0f;
 }
 
+__device float3 emissive_eval(const float3 Ng, const float3 I)
+{
+	float res = emissive_pdf(Ng, I);
+	
+	return make_float3(res, res, res);
+}
+
 __device float3 svm_emissive_eval(ShaderData *sd, ShaderClosure *sc)
 {
 	return emissive_eval(sd->Ng, sd->I);

Modified: trunk/blender/intern/cycles/render/light.cpp
===================================================================
--- trunk/blender/intern/cycles/render/light.cpp	2012-06-04 17:13:38 UTC (rev 47425)
+++ trunk/blender/intern/cycles/render/light.cpp	2012-06-04 17:17:10 UTC (rev 47426)
@@ -109,6 +109,9 @@
 
 	map_resolution = 512;
 
+	spot_angle = M_PI_F/4.0f;
+	spot_smooth = 0.0f;
+
 	cast_shadow = true;
 	shader = 0;
 }
@@ -451,6 +454,17 @@
 			light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z);
 			light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, dir.x, dir.y, dir.z);
 		}
+		else if(light->type == LIGHT_SPOT) {
+			shader_id &= ~SHADER_AREA_LIGHT;
+
+			float spot_angle = cosf(light->spot_angle*0.5f);
+			float spot_smooth = (1.0f - spot_angle)*light->spot_smooth;
+
+			light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
+			light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y);
+			light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f);
+			light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+		}
 	}
 	
 	device->tex_alloc("__light_data", dscene->light_data);

Modified: trunk/blender/intern/cycles/render/light.h
===================================================================
--- trunk/blender/intern/cycles/render/light.h	2012-06-04 17:13:38 UTC (rev 47425)
+++ trunk/blender/intern/cycles/render/light.h	2012-06-04 17:17:10 UTC (rev 47426)
@@ -48,6 +48,9 @@
 
 	int map_resolution;
 
+	float spot_angle;
+	float spot_smooth;
+
 	bool cast_shadow;
 
 	int shader;

Modified: trunk/blender/intern/cycles/util/util_math.h
===================================================================
--- trunk/blender/intern/cycles/util/util_math.h	2012-06-04 17:13:38 UTC (rev 47425)
+++ trunk/blender/intern/cycles/util/util_math.h	2012-06-04 17:17:10 UTC (rev 47426)
@@ -162,6 +162,12 @@
 		return f;
 }
 
+__device_inline float smoothstepf(float f)
+{
+	float ff = f*f;
+	return (3.0f*ff - 2.0f*ff*f);
+}
+
 /* Float2 Vector */
 
 #ifndef __KERNEL_OPENCL__




More information about the Bf-blender-cvs mailing list