From 0330741548ce87740f6976d8d2e6519eeb94625e Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 25 Nov 2016 18:59:43 +0100 Subject: [PATCH] Cycles: Add option to replace GI with AO approximation after certain amount of bounces This is a speed up option which is mainly useful for viewport. Gives nice speedup in the barbershop scene of 2x when replacing GI with AO after 2nd bounce without loosing too much details. Reviewers: brecht Subscribers: eyecandy, venomgfx Differential Revision: https://developer.blender.org/D2383 --- intern/cycles/blender/addon/properties.py | 14 ++++++++++++++ intern/cycles/blender/addon/ui.py | 10 +++++++++- intern/cycles/blender/blender_sync.cpp | 9 +++++++++ intern/cycles/kernel/kernel_path.h | 15 +++++++++++++++ intern/cycles/kernel/kernel_types.h | 4 ++-- intern/cycles/render/integrator.cpp | 9 +++++++++ intern/cycles/render/integrator.h | 2 ++ 7 files changed, 60 insertions(+), 3 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 802b9b76c5d..5c51f9afc28 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -638,6 +638,20 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): items=enum_texture_limit ) + cls.ao_bounces = IntProperty( + name="AO Bounces", + default=0, + description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature", + min=0, max=1024, + ) + + cls.ao_bounces_render = IntProperty( + name="AO Bounces Render", + default=0, + description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature", + min=0, max=1024, + ) + # Various fine-tuning debug flags def devices_update_callback(self, context): diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index ddcefaf4c01..44af5f7efed 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1038,10 +1038,11 @@ class CyclesWorld_PT_ambient_occlusion(CyclesButtonsPanel, Panel): layout = self.layout light = context.world.light_settings + scene = context.scene row = layout.row() sub = row.row() - sub.active = light.use_ambient_occlusion + sub.active = light.use_ambient_occlusion or scene.render.use_simplify sub.prop(light, "ao_factor", text="Factor") row.prop(light, "distance", text="Distance") @@ -1612,6 +1613,13 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel): row.active = cscene.use_distance_cull row.prop(cscene, "distance_cull_margin", text="Distance") + split = layout.split() + col = split.column() + col.prop(cscene, "ao_bounces") + + col = split.column() + col.prop(cscene, "ao_bounces_render") + def draw_device(self, context): scene = context.scene layout = self.layout diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index f8f2303ec76..d8043105cd8 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -322,6 +322,15 @@ void BlenderSync::sync_integrator() integrator->volume_samples = volume_samples; } + if(b_scene.render().use_simplify()) { + if(preview) { + integrator->ao_bounces = get_int(cscene, "ao_bounces"); + } + else { + integrator->ao_bounces = get_int(cscene, "ao_bounces_render"); + } + } + if(integrator->modified(previntegrator)) integrator->tag_update(scene); } diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 8ce9a4f02ec..f90701a8260 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -109,6 +109,10 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* intersect scene */ Intersection isect; uint visibility = path_state_ray_visibility(kg, state); + if(state->bounce > kernel_data.integrator.ao_bounces) { + visibility = PATH_RAY_SHADOW; + ray->t = kernel_data.background.ao_distance; + } bool hit = scene_intersect(kg, *ray, visibility, @@ -292,6 +296,9 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, break; } + else if(state->bounce > kernel_data.integrator.ao_bounces) { + break; + } /* setup shading */ shader_setup_from_ray(kg, @@ -627,6 +634,11 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, lcg_state = lcg_state_init(rng, &state, 0x51633e2d); } + if(state.bounce > kernel_data.integrator.ao_bounces) { + visibility = PATH_RAY_SHADOW; + ray.t = kernel_data.background.ao_distance; + } + bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax); #else bool hit = scene_intersect(kg, ray, visibility, &isect, NULL, 0.0f, 0.0f); @@ -769,6 +781,9 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, break; } + else if(state.bounce > kernel_data.integrator.ao_bounces) { + break; + } /* setup shading */ shader_setup_from_ray(kg, &sd, &isect, &ray); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index b7af90cd739..4d9c4b2e6f1 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -1143,6 +1143,8 @@ typedef struct KernelIntegrator { int max_transmission_bounce; int max_volume_bounce; + int ao_bounces; + /* transparent */ int transparent_min_bounce; int transparent_max_bounce; @@ -1185,8 +1187,6 @@ typedef struct KernelIntegrator { int volume_samples; float light_inv_rr_threshold; - - int pad1; } KernelIntegrator; static_assert_align(KernelIntegrator, 16); diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index a9a33d2e789..41e1dae2745 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -43,6 +43,8 @@ NODE_DEFINE(Integrator) SOCKET_INT(transparent_max_bounce, "Transparent Max Bounce", 7); SOCKET_BOOLEAN(transparent_shadows, "Transparent Shadows", false); + SOCKET_INT(ao_bounces, "AO Bounces", 0); + SOCKET_INT(volume_max_steps, "Volume Max Steps", 1024); SOCKET_FLOAT(volume_step_size, "Volume Step Size", 0.1f); @@ -111,6 +113,13 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene kintegrator->transparent_max_bounce = transparent_max_bounce + 1; kintegrator->transparent_min_bounce = transparent_min_bounce + 1; + if(ao_bounces == 0) { + kintegrator->ao_bounces = INT_MAX; + } + else { + kintegrator->ao_bounces = ao_bounces - 1; + } + /* Transparent Shadows * We only need to enable transparent shadows, if we actually have * transparent shaders in the scene. Otherwise we can disable it diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h index 17fdd0ef1db..f8cc0507ada 100644 --- a/intern/cycles/render/integrator.h +++ b/intern/cycles/render/integrator.h @@ -43,6 +43,8 @@ public: int transparent_max_bounce; bool transparent_shadows; + int ao_bounces; + int volume_max_steps; float volume_step_size;