[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [52234] trunk/blender/intern/cycles/kernel : Cycles: ambient occlusion now takes per-BSDF normals into account.

Brecht Van Lommel brechtvanlommel at pandora.be
Thu Nov 15 16:37:59 CET 2012


Revision: 52234
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=52234
Author:   blendix
Date:     2012-11-15 15:37:58 +0000 (Thu, 15 Nov 2012)
Log Message:
-----------
Cycles: ambient occlusion now takes per-BSDF normals into account.

Modified Paths:
--------------
    trunk/blender/intern/cycles/kernel/kernel_path.h
    trunk/blender/intern/cycles/kernel/kernel_shader.h

Modified: trunk/blender/intern/cycles/kernel/kernel_path.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_path.h	2012-11-15 14:08:46 UTC (rev 52233)
+++ trunk/blender/intern/cycles/kernel/kernel_path.h	2012-11-15 15:37:58 UTC (rev 52234)
@@ -331,12 +331,15 @@
 			float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
 			float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
 
+			float ao_factor = kernel_data.background.ao_factor;
+			float3 ao_N;
+			float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N);
 			float3 ao_D;
 			float ao_pdf;
 
-			sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
+			sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
 
-			if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
+			if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f && average(ao_bsdf) != 0.0f) {
 				Ray light_ray;
 				float3 ao_shadow;
 
@@ -347,11 +350,8 @@
 				light_ray.time = sd.time;
 #endif
 
-				if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
-					float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
-					ao_bsdf += shader_bsdf_ao(kg, &sd);
+				if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
 					path_radiance_accum_ao(&L, throughput, ao_bsdf, ao_shadow, state.bounce);
-				}
 			}
 		}
 #endif
@@ -509,12 +509,15 @@
 			float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
 			float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
 
+			float ao_factor = kernel_data.background.ao_factor;
+			float3 ao_N;
+			float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N);
 			float3 ao_D;
 			float ao_pdf;
 
-			sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
+			sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
 
-			if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
+			if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f && average(ao_bsdf) != 0.0f) {
 				Ray light_ray;
 				float3 ao_shadow;
 
@@ -525,11 +528,8 @@
 				light_ray.time = sd.time;
 #endif
 
-				if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
-					float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
-					ao_bsdf += shader_bsdf_ao(kg, &sd);
+				if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
 					path_radiance_accum_ao(L, throughput, ao_bsdf, ao_shadow, state.bounce);
-				}
 			}
 		}
 #endif
@@ -712,6 +712,8 @@
 			int num_samples = kernel_data.integrator.ao_samples;
 			float num_samples_inv = 1.0f/num_samples;
 			float ao_factor = kernel_data.background.ao_factor;
+			float3 ao_N;
+			float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N);
 
 			for(int j = 0; j < num_samples; j++) {
 				/* todo: solve correlation */
@@ -721,9 +723,9 @@
 				float3 ao_D;
 				float ao_pdf;
 
-				sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
+				sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
 
-				if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
+				if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f && average(ao_bsdf) != 0.0f) {
 					Ray light_ray;
 					float3 ao_shadow;
 
@@ -734,11 +736,8 @@
 					light_ray.time = sd.time;
 #endif
 
-					if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
-						float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*ao_factor;
-						ao_bsdf += shader_bsdf_ao(kg, &sd);
+					if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow))
 						path_radiance_accum_ao(&L, throughput*num_samples_inv, ao_bsdf, ao_shadow, state.bounce);
-					}
 				}
 			}
 		}

Modified: trunk/blender/intern/cycles/kernel/kernel_shader.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_shader.h	2012-11-15 14:08:46 UTC (rev 52233)
+++ trunk/blender/intern/cycles/kernel/kernel_shader.h	2012-11-15 15:37:58 UTC (rev 52234)
@@ -599,21 +599,35 @@
 #endif
 }
 
-__device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd)
+__device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N)
 {
 #ifdef __MULTI_CLOSURE__
 	float3 eval = make_float3(0.0f, 0.0f, 0.0f);
 
+	*N = make_float3(0.0f, 0.0f, 0.0f);
+
 	for(int i = 0; i< sd->num_closure; i++) {
 		ShaderClosure *sc = &sd->closure[i];
 
-		if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type))
+		if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
+			eval += sc->weight*ao_factor;
+			*N += sc->N*average(sc->weight);
+		}
+		if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type)) {
 			eval += sc->weight;
+			*N += sd->N*average(sc->weight);
+		}
 	}
 
+	*N = normalize(*N);
+
 	return eval;
 #else
-	if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
+	*N = sd->N;
+
+	if(CLOSURE_IS_DIFFUSE(sd->closure.type))
+		return sd->closure.weight*ao_factor;
+	else if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
 		return sd->closure.weight;
 	else
 		return make_float3(0.0f, 0.0f, 0.0f);




More information about the Bf-blender-cvs mailing list