[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44523] trunk/blender/intern/cycles: Cycles: ambient occlusion support, with AO factor and distance, and a render pass.

Brecht Van Lommel brechtvanlommel at pandora.be
Tue Feb 28 17:45:09 CET 2012


Revision: 44523
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44523
Author:   blendix
Date:     2012-02-28 16:45:08 +0000 (Tue, 28 Feb 2012)
Log Message:
-----------
Cycles: ambient occlusion support, with AO factor and distance, and a render pass.

http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/World#Ambient_Occlusion
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes#Lighting_Passes

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/addon/ui.py
    trunk/blender/intern/cycles/blender/blender_session.cpp
    trunk/blender/intern/cycles/blender/blender_shader.cpp
    trunk/blender/intern/cycles/kernel/kernel_accumulate.h
    trunk/blender/intern/cycles/kernel/kernel_passes.h
    trunk/blender/intern/cycles/kernel/kernel_path.h
    trunk/blender/intern/cycles/kernel/kernel_types.h
    trunk/blender/intern/cycles/render/background.cpp
    trunk/blender/intern/cycles/render/background.h
    trunk/blender/intern/cycles/render/film.cpp
    trunk/blender/intern/cycles/render/integrator.cpp

Modified: trunk/blender/intern/cycles/blender/addon/ui.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/ui.py	2012-02-28 16:45:01 UTC (rev 44522)
+++ trunk/blender/intern/cycles/blender/addon/ui.py	2012-02-28 16:45:08 UTC (rev 44523)
@@ -196,6 +196,7 @@
         col.prop(rl, "use_pass_material_index")
         col.prop(rl, "use_pass_emit")
         col.prop(rl, "use_pass_environment")
+        col.prop(rl, "use_pass_ambient_occlusion")
 
         col = split.column()
         col.label()
@@ -483,49 +484,68 @@
         if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'):
             layout.prop(world, "horizon_color", text="Color")
 
-
-class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel):
-    bl_label = "Settings"
+class CyclesWorld_PT_volume(CyclesButtonsPanel, Panel):
+    bl_label = "Volume"
     bl_context = "world"
     bl_options = {'DEFAULT_CLOSED'}
 
     @classmethod
     def poll(cls, context):
-        return context.world and CyclesButtonsPanel.poll(context)
+        # world = context.world
+        # world and world.node_tree and CyclesButtonsPanel.poll(context)
+        return False
 
     def draw(self, context):
         layout = self.layout
+        layout.active = False
 
         world = context.world
-        cworld = world.cycles
+        panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume')
 
-        col = layout.column()
+class CyclesWorld_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
+    bl_label = "Ambient Occlusion"
+    bl_context = "world"
 
-        col.prop(cworld, "sample_as_light")
-        row = col.row()
-        row.active = cworld.sample_as_light
-        row.prop(cworld, "sample_map_resolution")
+    @classmethod
+    def poll(cls, context):
+        return context.world and CyclesButtonsPanel.poll(context)
 
+    def draw_header(self, context):
+        light = context.world.light_settings
+        self.layout.prop(light, "use_ambient_occlusion", text="")
 
-class CyclesWorld_PT_volume(CyclesButtonsPanel, Panel):
-    bl_label = "Volume"
+    def draw(self, context):
+        layout = self.layout
+        light = context.world.light_settings
+
+        layout.active = light.use_ambient_occlusion
+
+        split = layout.split()
+        split.prop(light, "ao_factor", text="Factor")
+        split.prop(light, "distance", text="Distance")
+
+class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel):
+    bl_label = "Settings"
     bl_context = "world"
     bl_options = {'DEFAULT_CLOSED'}
 
     @classmethod
     def poll(cls, context):
-        # world = context.world
-        # world and world.node_tree and CyclesButtonsPanel.poll(context)
-        return False
+        return context.world and CyclesButtonsPanel.poll(context)
 
     def draw(self, context):
         layout = self.layout
-        layout.active = False
 
         world = context.world
-        panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume')
+        cworld = world.cycles
 
+        col = layout.column()
 
+        col.prop(cworld, "sample_as_light")
+        row = col.row()
+        row.active = cworld.sample_as_light
+        row.prop(cworld, "sample_map_resolution")
+
 class CyclesMaterial_PT_surface(CyclesButtonsPanel, Panel):
     bl_label = "Surface"
     bl_context = "material"

Modified: trunk/blender/intern/cycles/blender/blender_session.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_session.cpp	2012-02-28 16:45:01 UTC (rev 44522)
+++ trunk/blender/intern/cycles/blender/blender_session.cpp	2012-02-28 16:45:08 UTC (rev 44523)
@@ -158,10 +158,11 @@
 			return PASS_EMISSION;
 		case BL::RenderPass::type_ENVIRONMENT:
 			return PASS_BACKGROUND;
+		case BL::RenderPass::type_AO:
+			return PASS_AO;
 
 		case BL::RenderPass::type_DIFFUSE:
 		case BL::RenderPass::type_SHADOW:
-		case BL::RenderPass::type_AO:
 		case BL::RenderPass::type_COLOR:
 		case BL::RenderPass::type_REFRACTION:
 		case BL::RenderPass::type_SPECULAR:

Modified: trunk/blender/intern/cycles/blender/blender_shader.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_shader.cpp	2012-02-28 16:45:01 UTC (rev 44522)
+++ trunk/blender/intern/cycles/blender/blender_shader.cpp	2012-02-28 16:45:08 UTC (rev 44523)
@@ -696,6 +696,20 @@
 			graph->connect(closure->output("Background"), out->input("Surface"));
 		}
 
+		/* AO */
+		if(b_world) {
+			BL::WorldLighting b_light = b_world.light_settings();
+
+			if(b_light.use_ambient_occlusion()) {
+				background->ao_factor = b_light.ao_factor();
+				background->ao_distance = b_light.distance();
+			}
+			else {
+				background->ao_factor = 0.0f;
+				background->ao_distance = 0.0f;
+			}
+		}
+
 		shader->set_graph(graph);
 		shader->tag_update(scene);
 	}

Modified: trunk/blender/intern/cycles/kernel/kernel_accumulate.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_accumulate.h	2012-02-28 16:45:01 UTC (rev 44522)
+++ trunk/blender/intern/cycles/kernel/kernel_accumulate.h	2012-02-28 16:45:08 UTC (rev 44523)
@@ -135,6 +135,7 @@
 
 		L->emission = make_float3(0.0f, 0.0f, 0.0f);
 		L->background = make_float3(0.0f, 0.0f, 0.0f);
+		L->ao = make_float3(0.0f, 0.0f, 0.0f);
 	}
 	else
 		L->emission = make_float3(0.0f, 0.0f, 0.0f);
@@ -199,6 +200,27 @@
 #endif
 }
 
+__device_inline void path_radiance_accum_ao(PathRadiance *L, float3 throughput, float3 bsdf, float3 ao, int bounce)
+{
+#ifdef __PASSES__
+	if(L->use_light_pass) {
+		if(bounce == 0) {
+			/* directly visible lighting */
+			L->direct_diffuse += throughput*bsdf*ao;
+			L->ao += throughput*ao;
+		}
+		else {
+			/* indirectly visible lighting after BSDF bounce */
+			L->indirect += throughput*bsdf*ao;
+		}
+	}
+	else
+		L->emission += throughput*bsdf*ao;
+#else
+	*L += throughput*bsdf*ao;
+#endif
+}
+
 __device_inline void path_radiance_accum_light(PathRadiance *L, float3 throughput, BsdfEval *bsdf_eval, int bounce)
 {
 #ifdef __PASSES__

Modified: trunk/blender/intern/cycles/kernel/kernel_passes.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_passes.h	2012-02-28 16:45:01 UTC (rev 44522)
+++ trunk/blender/intern/cycles/kernel/kernel_passes.h	2012-02-28 16:45:08 UTC (rev 44523)
@@ -123,6 +123,8 @@
 		kernel_write_pass_float3(buffer + kernel_data.film.pass_emission, sample, L->emission);
 	if(flag & PASS_BACKGROUND)
 		kernel_write_pass_float3(buffer + kernel_data.film.pass_background, sample, L->background);
+	if(flag & PASS_AO)
+		kernel_write_pass_float3(buffer + kernel_data.film.pass_ao, sample, L->ao);
 
 	if(flag & PASS_DIFFUSE_COLOR)
 		kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_color, sample, L->color_diffuse);

Modified: trunk/blender/intern/cycles/kernel/kernel_path.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_path.h	2012-02-28 16:45:01 UTC (rev 44522)
+++ trunk/blender/intern/cycles/kernel/kernel_path.h	2012-02-28 16:45:08 UTC (rev 44523)
@@ -145,13 +145,16 @@
 	return average(throughput);
 }
 
-__device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, Intersection *isect, BsdfEval *L_light)
+__device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, float3 *shadow)
 {
 	if(ray->t == 0.0f)
 		return false;
 	
-	bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, isect);
+	Intersection isect;
+	bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect);
 
+	*shadow = make_float3(1.0f, 1.0f, 1.0f);
+
 #ifdef __TRANSPARENT_SHADOWS__
 	if(result && kernel_data.integrator.transparent_shadows) {
 		/* transparent shadows work in such a way to try to minimize overhead
@@ -162,7 +165,7 @@
 		   
 		   also note that for this to work correct, multi close sampling must
 		   be used, since we don't pass a random number to shader_eval_surface */
-		if(shader_transparent_shadow(kg, isect)) {
+		if(shader_transparent_shadow(kg, &isect)) {
 			float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
 			float3 Pend = ray->P + ray->D*ray->t;
 			int bounce = state->transparent_bounce;
@@ -184,16 +187,16 @@
 #endif
 				}
 
-				if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, isect)) {
-					bsdf_eval_mul(L_light, throughput);
+				if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, &isect)) {
+					*shadow *= throughput;
 					return false;
 				}
 
-				if(!shader_transparent_shadow(kg, isect))
+				if(!shader_transparent_shadow(kg, &isect))
 					return true;
 
 				ShaderData sd;
-				shader_setup_from_ray(kg, &sd, isect, ray);
+				shader_setup_from_ray(kg, &sd, &isect, ray);
 				shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW);
 
 				throughput *= shader_bsdf_transparency(kg, &sd);
@@ -285,6 +288,35 @@
 
 		throughput /= probability;
 
+
+#ifdef __AO__
+		/* ambient occlusion */
+		if(kernel_data.integrator.use_ambient_occlusion) {
+			/* todo: solve correlation */
+			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);
+
+			float3 ao_D;
+			float ao_pdf;
+
+			sample_cos_hemisphere(sd.N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
+
+			if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
+				Ray light_ray;
+				float3 ao_shadow;
+
+				light_ray.P = ray_offset(sd.P, sd.Ng);
+				light_ray.D = ao_D;
+				light_ray.t = kernel_data.background.ao_distance;
+
+				if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
+					float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
+					path_radiance_accum_ao(&L, throughput, ao_bsdf, ao_shadow, state.bounce);
+				}
+			}
+		}
+#endif
+
 #ifdef __EMISSION__
 		if(kernel_data.integrator.use_direct_light) {
 			/* sample illumination from lights to find path contribution */
@@ -307,8 +339,13 @@
 #endif
 					if(direct_emission(kg, &sd, i, light_t, light_o, light_u, light_v, &light_ray, &L_light)) {
 						/* trace shadow ray */
-						if(!shadow_blocked(kg, &state, &light_ray, &isect, &L_light))
+						float3 shadow;
+
+						if(!shadow_blocked(kg, &state, &light_ray, &shadow)) {
+							/* accumulate */
+							bsdf_eval_mul(&L_light, shadow);
 							path_radiance_accum_light(&L, throughput, &L_light, state.bounce);
+						}
 					}
 #ifdef __MULTI_LIGHT__
 				}


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list