Cycles: change AO bounces approximation to do more glossy and transmission.

Rather than treating all ray types equally, we now always render 1 glossy
bounce and unlimited transmission bounces. This makes it possible to get
good looking results with low AO bounces settings, making it useful to
speed up interior renders for example.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D2818
This commit is contained in:
Mathieu Menuet 2017-09-12 15:13:55 +02:00 committed by Brecht Van Lommel
parent d2202117fe
commit 659ba012b0
Notes: blender-bot 2023-02-14 08:38:11 +01:00
Referenced by issue #53349, Cycles - difference between OpenCL and CUDA with AO simplify
4 changed files with 31 additions and 12 deletions

View File

@ -111,7 +111,7 @@ 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) {
if(path_state_ao_bounce(kg, state)) {
visibility = PATH_RAY_SHADOW;
ray->t = kernel_data.background.ao_distance;
}
@ -294,7 +294,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
break;
}
else if(state->bounce > kernel_data.integrator.ao_bounces) {
else if(path_state_ao_bounce(kg, state)) {
break;
}
@ -473,13 +473,18 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
lcg_state = lcg_state_init(&state, 0x51633e2d);
}
if(state.bounce > kernel_data.integrator.ao_bounces) {
if(path_state_ao_bounce(kg, &state)) {
visibility = PATH_RAY_SHADOW;
ray.t = kernel_data.background.ao_distance;
}
bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax);
#else
if(path_state_ao_bounce(kg, state)) {
visibility = PATH_RAY_SHADOW;
ray.t = kernel_data.background.ao_distance;
}
bool hit = scene_intersect(kg, ray, visibility, &isect, NULL, 0.0f, 0.0f);
#endif /* __HAIR__ */
@ -620,7 +625,7 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
break;
}
else if(state.bounce > kernel_data.integrator.ao_bounces) {
else if(path_state_ao_bounce(kg, &state)) {
break;
}

View File

@ -143,7 +143,7 @@ ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathSta
#endif
}
ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg, PathState *state)
ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg, ccl_addr_space PathState *state)
{
uint flag = state->flag & PATH_RAY_ALL_VISIBILITY;
@ -214,5 +214,15 @@ ccl_device_inline void path_state_modify_bounce(ccl_addr_space PathState *state,
state->bounce -= 1;
}
ccl_device_inline bool path_state_ao_bounce(KernelGlobals *kg, ccl_addr_space PathState *state)
{
if(state->bounce <= kernel_data.integrator.ao_bounces) {
return false;
}
int bounce = state->bounce - state->transmission_bounce - (state->glossy_bounce > 0);
return (bounce > kernel_data.integrator.ao_bounces);
}
CCL_NAMESPACE_END

View File

@ -33,7 +33,7 @@ ccl_device void kernel_indirect_background(KernelGlobals *kg)
if(ray_index != QUEUE_EMPTY_SLOT) {
if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
if(state->bounce > kernel_data.integrator.ao_bounces) {
if(path_state_ao_bounce(kg, state)) {
kernel_split_path_end(kg, ray_index);
}
}

View File

@ -60,13 +60,13 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg)
}
Intersection isect;
PathState state = kernel_split_state.path_state[ray_index];
ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
Ray ray = kernel_split_state.ray[ray_index];
/* intersect scene */
uint visibility = path_state_ray_visibility(kg, &state);
uint visibility = path_state_ray_visibility(kg, state);
if(state.bounce > kernel_data.integrator.ao_bounces) {
if(path_state_ao_bounce(kg, state)) {
visibility = PATH_RAY_SHADOW;
ray.t = kernel_data.background.ao_distance;
}
@ -76,18 +76,22 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg)
uint lcg_state = 0;
if(kernel_data.bvh.have_curves) {
if((kernel_data.cam.resolution == 1) && (state.flag & PATH_RAY_CAMERA)) {
if((kernel_data.cam.resolution == 1) && (state->flag & PATH_RAY_CAMERA)) {
float3 pixdiff = ray.dD.dx + ray.dD.dy;
/*pixdiff = pixdiff - dot(pixdiff, ray.D)*ray.D;*/
difl = kernel_data.curve.minimum_width * len(pixdiff) * 0.5f;
}
extmax = kernel_data.curve.maximum_width;
lcg_state = lcg_state_init(&state, 0x51633e2d);
lcg_state = lcg_state_init_addrspace(state, 0x51633e2d);
}
bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax);
#else
if(path_state_ao_bounce(kg, state)) {
visibility = PATH_RAY_SHADOW;
ray.t = kernel_data.background.ao_distance;
}
bool hit = scene_intersect(kg, ray, visibility, &isect, NULL, 0.0f, 0.0f);
#endif
kernel_split_state.isect[ray_index] = isect;
@ -95,7 +99,7 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg)
#ifdef __KERNEL_DEBUG__
PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
if(state.flag & PATH_RAY_CAMERA) {
if(state->flag & PATH_RAY_CAMERA) {
L->debug_data.num_bvh_traversed_nodes += isect.num_traversed_nodes;
L->debug_data.num_bvh_traversed_instances += isect.num_traversed_instances;
L->debug_data.num_bvh_intersections += isect.num_intersections;