[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