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
This commit is contained in:
Sergey Sharybin 2016-11-25 18:59:43 +01:00
parent 84b18162cf
commit 0330741548
7 changed files with 60 additions and 3 deletions

@ -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):

@ -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

@ -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);
}

@ -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);

@ -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);

@ -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

@ -43,6 +43,8 @@ public:
int transparent_max_bounce;
bool transparent_shadows;
int ao_bounces;
int volume_max_steps;
float volume_step_size;