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
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-12-02 14:54:48 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-12-02 14:54:48 +0300
commit927b976a88a836c94651b07210f0d635d33500ef (patch)
tree98eee20532c5ea9368e79fc3c7792f52b4307aae /source/blender
parent03a9740c16861511fec9908fa0afe4d42620773d (diff)
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/makesdna/DNA_world_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_world.c5
-rw-r--r--source/blender/render/intern/source/occlusion.c77
3 files changed, 60 insertions, 25 deletions
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index 11ecbf97d97..9b3f78caee0 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -107,7 +107,8 @@ typedef struct World {
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) */
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index 88992387148..231faffef0f 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -318,6 +318,11 @@ static void rna_def_ambient_occlusion(BlenderRNA *brna)
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)
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index 90929db2f74..3a5680eaf70 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -111,6 +111,7 @@ typedef struct OcclusionTree {
int dothreadedbuild;
int totbuildthread;
+ int doindirect;
OcclusionCache *cache;
} OcclusionTree;
@@ -652,6 +653,7 @@ static OcclusionTree *occ_tree_build(Render *re)
/* 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 @@ static OcclusionTree *occ_tree_build(Render *re)
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 @@ static OcclusionTree *occ_tree_build(Render *re)
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 @@ static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float
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 @@ static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass)
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 @@ static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass)
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 @@ static void sample_occ_tree(Render *re, OcclusionTree *tree, OccFace *exclude, f
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 @@ void make_occ_tree(Render *re)
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)