[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25070] trunk/blender: AAO Indirect Diffuse

Brecht Van Lommel brecht at blender.org
Wed Dec 2 12:54:49 CET 2009


Revision: 25070
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25070
Author:   blendix
Date:     2009-12-02 12:54:48 +0100 (Wed, 02 Dec 2009)

Log Message:
-----------
AAO Indirect Diffuse

Don't use passes anymore for indirect lighting, people were using this
probably thinking it would do bounces, but that's not the intention of
this feature, it is to reduce problems with light bleeding. I want to
remove this option for AO as well, but will leave it in for now until
there is a better alternative.

Added bounces option for indirect, could be implemented much better,
but perhaps useful for testing now. Existing files need to set this to
1 to get the same results again.

Modified Paths:
--------------
    trunk/blender/release/scripts/ui/properties_world.py
    trunk/blender/source/blender/makesdna/DNA_world_types.h
    trunk/blender/source/blender/makesrna/intern/rna_world.c
    trunk/blender/source/blender/render/intern/source/occlusion.c

Modified: trunk/blender/release/scripts/ui/properties_world.py
===================================================================
--- trunk/blender/release/scripts/ui/properties_world.py	2009-12-02 11:23:11 UTC (rev 25069)
+++ trunk/blender/release/scripts/ui/properties_world.py	2009-12-02 11:54:48 UTC (rev 25070)
@@ -224,6 +224,7 @@
         if wide_ui:
             col = split.column()
         col.prop(ao, "color")
+        col.prop(ao, "indirect_bounces")
 
 bpy.types.register(WORLD_PT_context_world)
 bpy.types.register(WORLD_PT_preview)

Modified: trunk/blender/source/blender/makesdna/DNA_world_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_world_types.h	2009-12-02 11:23:11 UTC (rev 25069)
+++ trunk/blender/source/blender/makesdna/DNA_world_types.h	2009-12-02 11:54:48 UTC (rev 25070)
@@ -107,7 +107,8 @@
 	short aomode, aosamp, aomix, aocolor;
 	float ao_adapt_thresh, ao_adapt_speed_fac;
 	float ao_approx_error, ao_approx_correction;
-	float ao_indirect_energy, aopad;
+	float ao_indirect_energy;
+	short ao_indirect_bounces, ao_pad;
 	short ao_samp_method, ao_gather_method, ao_approx_passes;
 	
 	/* assorted settings (in the middle of ambient occlusion settings for padding reasons) */

Modified: trunk/blender/source/blender/makesrna/intern/rna_world.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_world.c	2009-12-02 11:23:11 UTC (rev 25069)
+++ trunk/blender/source/blender/makesrna/intern/rna_world.c	2009-12-02 11:54:48 UTC (rev 25070)
@@ -318,6 +318,11 @@
 	RNA_def_property_ui_range(prop, 0, 10, 0.1, 3);
 	RNA_def_property_ui_text(prop, "Indirect", "Use approximate ambient occlusion for indirect diffuse lighting.");
 	RNA_def_property_update(prop, 0, "rna_World_update");
+
+	prop= RNA_def_property(srna, "indirect_bounces", PROP_INT, PROP_UNSIGNED);
+	RNA_def_property_int_sdna(prop, NULL, "ao_indirect_bounces");
+	RNA_def_property_ui_text(prop, "Bounces", "Number of indirect diffuse light bounces to use for approximate ambient occlusion.");
+	RNA_def_property_update(prop, 0, "rna_World_update");
 }
 
 static void rna_def_world_mist(BlenderRNA *brna)

Modified: trunk/blender/source/blender/render/intern/source/occlusion.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/occlusion.c	2009-12-02 11:23:11 UTC (rev 25069)
+++ trunk/blender/source/blender/render/intern/source/occlusion.c	2009-12-02 11:54:48 UTC (rev 25070)
@@ -111,6 +111,7 @@
 
 	int dothreadedbuild;
 	int totbuildthread;
+	int doindirect;
 
 	OcclusionCache *cache;
 } OcclusionTree;
@@ -652,6 +653,7 @@
 	/* parameters */
 	tree->error= get_render_aosss_error(&re->r, re->wrld.ao_approx_error);
 	tree->distfac= (re->wrld.aomode & WO_AODIST)? re->wrld.aodistfac: 0.0f;
+	tree->doindirect= (re->wrld.ao_indirect_energy > 0.0f && re->wrld.ao_indirect_bounces > 0);
 
 	/* allocation */
 	tree->arena= BLI_memarena_new(0x8000 * sizeof(OccNode));
@@ -664,7 +666,7 @@
 	tree->co= MEM_callocN(sizeof(float)*3*totface, "OcclusionCo");
 	tree->occlusion= MEM_callocN(sizeof(float)*totface, "OcclusionOcclusion");
 
-	if(re->wrld.ao_indirect_energy != 0.0f)
+	if(tree->doindirect)
 		tree->rad= MEM_callocN(sizeof(float)*3*totface, "OcclusionRad");
 
 	/* make array of face pointers */
@@ -693,7 +695,7 @@
 	tree->maxdepth= 1;
 	occ_build_recursive(tree, tree->root, 0, totface, 1);
 
-	if(re->wrld.ao_indirect_energy != 0.0f) {
+	if(tree->doindirect) {
 		occ_build_shade(re, tree);
 		occ_sum_occlusion(tree, tree->root);
 	}
@@ -1299,14 +1301,53 @@
 	if(bentn) normalize_v3(bentn);
 }
 
+static void occ_compute_bounces(Render *re, OcclusionTree *tree, int totbounce)
+{
+	float (*rad)[3], (*sum)[3], (*tmp)[3], co[3], n[3], occ;
+	int bounce, i;
+
+	rad= MEM_callocN(sizeof(float)*3*tree->totface, "OcclusionBounceRad");
+	sum= MEM_dupallocN(tree->rad);
+
+	for(bounce=1; bounce<totbounce; bounce++) {
+		for(i=0; i<tree->totface; i++) {
+			occ_face(&tree->face[i], co, n, NULL);
+			madd_v3_v3fl(co, n, 1e-8f);
+
+			occ_lookup(tree, 0, &tree->face[i], co, n, &occ, rad[i], NULL);
+			rad[i][0]= MAX2(rad[i][0], 0.0f);
+			rad[i][1]= MAX2(rad[i][1], 0.0f);
+			rad[i][2]= MAX2(rad[i][2], 0.0f);
+			add_v3_v3(sum[i], rad[i]);
+
+			if(re->test_break(re->tbh))
+				break;
+		}
+
+		if(re->test_break(re->tbh))
+			break;
+
+		tmp= tree->rad;
+		tree->rad= rad;
+		rad= tmp;
+
+		occ_sum_occlusion(tree, tree->root);
+	}
+
+	MEM_freeN(rad);
+	MEM_freeN(tree->rad);
+	tree->rad= sum;
+
+	if(!re->test_break(re->tbh))
+		occ_sum_occlusion(tree, tree->root);
+}
+
 static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass)
 {
-	float *occ, (*rad)[3]= NULL, co[3], n[3];
+	float *occ, co[3], n[3];
 	int pass, i;
 	
 	occ= MEM_callocN(sizeof(float)*tree->totface, "OcclusionPassOcc");
-	if(tree->rad)
-		rad= MEM_callocN(sizeof(float)*3*tree->totface, "OcclusionPassRad");
 
 	for(pass=0; pass<totpass; pass++) {
 		for(i=0; i<tree->totface; i++) {
@@ -1314,7 +1355,7 @@
 			negate_v3(n);
 			VECADDFAC(co, co, n, 1e-8f);
 
-			occ_lookup(tree, 0, &tree->face[i], co, n, &occ[i], NULL, (rad)? rad[i]: NULL);
+			occ_lookup(tree, 0, &tree->face[i], co, n, &occ[i], NULL, NULL);
 			if(re->test_break(re->tbh))
 				break;
 		}
@@ -1326,41 +1367,27 @@
 			tree->occlusion[i] -= occ[i]; //MAX2(1.0f-occ[i], 0.0f);
 			if(tree->occlusion[i] < 0.0f)
 				tree->occlusion[i]= 0.0f;
-
-			if(rad) {
-				sub_v3_v3(tree->rad[i], rad[i]);
-
-				if(tree->rad[i][0] < 0.0f)
-					tree->rad[i][0]= 0.0f;
-				if(tree->rad[i][1] < 0.0f)
-					tree->rad[i][1]= 0.0f;
-				if(tree->rad[i][2] < 0.0f)
-					tree->rad[i][2]= 0.0f;
-			}
 		}
 
 		occ_sum_occlusion(tree, tree->root);
 	}
 
 	MEM_freeN(occ);
-	if(rad)
-		MEM_freeN(rad);
 }
 
 static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, float *co, float *n, int thread, int onlyshadow, float *ao, float *indirect)
 {
 	float nn[3], bn[3], fac, occ, occlusion, correction, rad[3];
-	int aocolor, aorad;
+	int aocolor;
 
 	aocolor= re->wrld.aocolor;
 	if(onlyshadow)
 		aocolor= WO_AOPLAIN;
-	aorad= (re->wrld.ao_indirect_energy != 0.0f);
 
 	VECCOPY(nn, n);
 	negate_v3(nn);
 
-	occ_lookup(tree, thread, exclude, co, nn, &occ, (aorad)? rad: NULL, (aocolor)? bn: NULL);
+	occ_lookup(tree, thread, exclude, co, nn, &occ, (tree->doindirect)? rad: NULL, (aocolor)? bn: NULL);
 
 	correction= re->wrld.ao_approx_correction;
 
@@ -1398,7 +1425,7 @@
 		ao[2]= occlusion;
 	}
 
-	if(aorad) copy_v3_v3(indirect, rad);
+	if(tree->doindirect) copy_v3_v3(indirect, rad);
 	else zero_v3(indirect);
 }
 
@@ -1600,8 +1627,10 @@
 	re->occlusiontree= occ_tree_build(re);
 	
 	if(re->occlusiontree) {
-		if(re->wrld.ao_approx_passes)
+		if(re->wrld.ao_approx_passes > 0)
 			occ_compute_passes(re, re->occlusiontree, re->wrld.ao_approx_passes);
+		if(re->wrld.ao_indirect_bounces > 1)
+			occ_compute_bounces(re, re->occlusiontree, re->wrld.ao_indirect_bounces);
 
 		for(mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
 			if(!mesh->face || !mesh->co || !mesh->ao)





More information about the Bf-blender-cvs mailing list