[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12745] trunk/blender/source/blender: Italian community request: Area light fix!

Ton Roosendaal ton at blender.org
Sat Dec 1 18:55:16 CET 2007


Revision: 12745
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12745
Author:   ton
Date:     2007-12-01 18:55:16 +0100 (Sat, 01 Dec 2007)

Log Message:
-----------
Italian community request: Area light fix!

http://peach.blender.org/index.php/area-light-fix-light-not-shadow/

Now, for every possible shadow sample, an area light calculation is 
done from that position.

Modified Paths:
--------------
    trunk/blender/source/blender/render/intern/source/convertblender.c
    trunk/blender/source/blender/render/intern/source/rayshade.c
    trunk/blender/source/blender/render/intern/source/shadeoutput.c
    trunk/blender/source/blender/src/space.c

Modified: trunk/blender/source/blender/render/intern/source/convertblender.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/convertblender.c	2007-12-01 14:36:06 UTC (rev 12744)
+++ trunk/blender/source/blender/render/intern/source/convertblender.c	2007-12-01 17:55:16 UTC (rev 12745)
@@ -2940,8 +2940,13 @@
 
 static void area_lamp_vectors(LampRen *lar)
 {
-	float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey;
+	float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey, multifac;
 
+	/* make it smaller, so area light can be multisampled */
+	multifac= 1.0f/sqrt((float)lar->ray_totsamp);
+	xsize *= multifac;
+	ysize *= multifac;
+	
 	/* corner vectors */
 	lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
 	lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
@@ -3076,6 +3081,7 @@
 		}
 
 		area_lamp_vectors(lar);
+		init_jitter_plane(lar);	// subsamples
 	}
 	else lar->ray_totsamp= 0;
 	

Modified: trunk/blender/source/blender/render/intern/source/rayshade.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/rayshade.c	2007-12-01 14:36:06 UTC (rev 12744)
+++ trunk/blender/source/blender/render/intern/source/rayshade.c	2007-12-01 17:55:16 UTC (rev 12745)
@@ -579,6 +579,9 @@
 	float *fp;
 	int x, iter=12, tot= lar->ray_totsamp;
 	
+	/* test if already initialized */
+	if(lar->jitter) return;
+	
 	/* at least 4, or max threads+1 tables */
 	if(BLENDER_MAX_THREADS < 4) x= 4;
 	else x= BLENDER_MAX_THREADS+1;

Modified: trunk/blender/source/blender/render/intern/source/shadeoutput.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/shadeoutput.c	2007-12-01 14:36:06 UTC (rev 12744)
+++ trunk/blender/source/blender/render/intern/source/shadeoutput.c	2007-12-01 17:55:16 UTC (rev 12745)
@@ -421,18 +421,22 @@
 }
 
 /* Stoke's form factor. Need doubles here for extreme small area sizes */
-static float area_lamp_energy(float *co, float *vn, LampRen *lar)
+static float area_lamp_energy(float (*area)[3], float *co, float *vn)
 {
 	double fac;
 	double vec[4][3];	/* vectors of rendered co to vertices lamp */
 	double cross[4][3];	/* cross products of this */
 	double rad[4];		/* angles between vecs */
 
-	VECSUB(vec[0], co, lar->area[0]);
-	VECSUB(vec[1], co, lar->area[1]);
-	VECSUB(vec[2], co, lar->area[2]);
-	VECSUB(vec[3], co, lar->area[3]);
+	/* extra test for dot */
+	if ( INPR(co, vn) <= 0.0f)
+		return 0.0f;
 	
+	VECSUB(vec[0], co, area[0]);
+	VECSUB(vec[1], co, area[1]);
+	VECSUB(vec[2], co, area[2]);
+	VECSUB(vec[3], co, area[3]);
+	
 	Normalize_d(vec[0]);
 	Normalize_d(vec[1]);
 	Normalize_d(vec[2]);
@@ -467,9 +471,37 @@
 	fac+= rad[3]*(vn[0]*cross[3][0]+ vn[1]*cross[3][1]+ vn[2]*cross[3][2]);
 
 	if(fac<=0.0) return 0.0;
-	return pow(fac*lar->areasize, lar->k);	// corrected for buttons size and lar->dist^2
+	return fac;
 }
 
+static float area_lamp_energy_multisample(LampRen *lar, float *co, float *vn)
+{
+	/* corner vectors are moved around according lamp jitter */
+	float *jitlamp= lar->jitter, vec[3];
+	float area[4][3], intens= 0.0f;
+	int a= lar->ray_totsamp;
+	
+	
+	while(a--) {
+		vec[0]= jitlamp[0];
+		vec[1]= jitlamp[1];
+		vec[2]= 0.0f;
+		Mat3MulVecfl(lar->mat, vec);
+		
+		VECADD(area[0], lar->area[0], vec);
+		VECADD(area[1], lar->area[1], vec);
+		VECADD(area[2], lar->area[2], vec);
+		VECADD(area[3], lar->area[3], vec);
+		
+		intens+= area_lamp_energy(area, co, vn);
+		
+		jitlamp+= 2;
+	}
+	intens /= (float)lar->ray_totsamp;
+	
+	return pow(intens*lar->areasize, lar->k);	// corrected for buttons size and lar->dist^2
+}
+
 static float spec(float inp, int hard)	
 {
 	float b1;
@@ -1057,10 +1089,10 @@
 		/* area type has no quad or sphere option */
 		if(lar->type==LA_AREA) {
 			/* area is single sided */
-			if(INPR(lv, lar->vec) > 0.0f)
-				visifac= 1.0f;
-			else
-				visifac= 0.0f;
+			//if(INPR(lv, lar->vec) > 0.0f)
+			//	visifac= 1.0f;
+			//else
+			//	visifac= 0.0f;
 		}
 		else {
 			switch(lar->falloff_type)
@@ -1206,7 +1238,7 @@
 	/* this complex construction screams for a nicer implementation! (ton) */
 	if(R.r.mode & R_SHADOW) {
 		if(ma->mode & MA_SHADOW) {
-			if(lar->type==LA_HEMI);
+			if(lar->type==LA_HEMI || lar->type==LA_AREA);
 			else if((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) {
 				float thresh= vlr->ob->smoothresh;
 				if(inp>thresh)
@@ -1233,7 +1265,7 @@
 	else {
 		
 		if(lar->type==LA_AREA)
-			inp= area_lamp_energy(shi->co, vn, lar);
+			inp= area_lamp_energy_multisample(lar, shi->co, vn);
 		
 		/* diffuse shaders (oren nayer gets inp from area light) */
 		if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness);

Modified: trunk/blender/source/blender/src/space.c
===================================================================
--- trunk/blender/source/blender/src/space.c	2007-12-01 14:36:06 UTC (rev 12744)
+++ trunk/blender/source/blender/src/space.c	2007-12-01 17:55:16 UTC (rev 12745)
@@ -2369,7 +2369,7 @@
 						ob= ob->parent;
 					if(ob && (ob->flag & OB_POSEMODE)) {
 						bArmature *arm= ob->data;
-						if( ELEM(arm->drawtype, ARM_B_BONE, ARM_ENVELOPE)) {
+						if( arm->drawtype==ARM_ENVELOPE) {
 							initTransform(TFM_BONESIZE, CTX_NONE);
 							Transform();
 							break;





More information about the Bf-blender-cvs mailing list