diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index 1e99f2cb99f..fffa9afb342 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -510,7 +510,7 @@ ccl_device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 return t*t/cos_pi; } -ccl_device_inline void lamp_light_sample(KernelGlobals *kg, +ccl_device_inline bool lamp_light_sample(KernelGlobals *kg, int lamp, float randu, float randv, float3 P, @@ -581,6 +581,9 @@ ccl_device_inline void lamp_light_sample(KernelGlobals *kg, /* spot light attenuation */ float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2); ls->eval_fac *= spot_light_attenuation(data1, data2, ls); + if(ls->eval_fac == 0.0f) { + return false; + } } ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t); } @@ -593,6 +596,10 @@ ccl_device_inline void lamp_light_sample(KernelGlobals *kg, float3 axisv = make_float3(data2.y, data2.z, data2.w); float3 D = make_float3(data3.y, data3.z, data3.w); + if(dot(ls->P - P, D) > 0.0f) { + return false; + } + ls->pdf = area_light_sample(P, &ls->P, axisu, axisv, randu, randv, @@ -603,13 +610,12 @@ ccl_device_inline void lamp_light_sample(KernelGlobals *kg, float invarea = data2.x; ls->eval_fac = 0.25f*invarea; - - if(dot(ls->D, D) > 0.0f) - ls->pdf = 0.0f; } ls->eval_fac *= kernel_data.integrator.inv_pdf_lights; } + + return (ls->pdf > 0.0f); } ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls) @@ -836,7 +842,7 @@ ccl_device bool light_select_reached_max_bounces(KernelGlobals *kg, int index, i return (bounce > __float_as_int(data4.x)); } -ccl_device_noinline void light_sample(KernelGlobals *kg, +ccl_device_noinline bool light_sample(KernelGlobals *kg, float randt, float randu, float randv, @@ -857,21 +863,20 @@ ccl_device_noinline void light_sample(KernelGlobals *kg, int shader_flag = __float_as_int(l.z); triangle_light_sample(kg, prim, object, randu, randv, time, ls); - /* compute incoming direction, distance and pdf */ ls->D = normalize_len(ls->P - P, &ls->t); ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t); ls->shader |= shader_flag; + return (ls->pdf > 0.0f); } else { int lamp = -prim-1; if(UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) { - ls->pdf = 0.0f; - return; + return false; } - lamp_light_sample(kg, lamp, randu, randv, P, ls); + return lamp_light_sample(kg, lamp, randu, randv, P, ls); } } diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h index 250b8e92a45..27acf8166b3 100644 --- a/intern/cycles/kernel/kernel_path_surface.h +++ b/intern/cycles/kernel/kernel_path_surface.h @@ -54,15 +54,15 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobal path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); LightSample ls; - lamp_light_sample(kg, i, light_u, light_v, ccl_fetch(sd, P), &ls); + if(lamp_light_sample(kg, i, light_u, light_v, ccl_fetch(sd, P), &ls)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; - if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { - /* trace shadow ray */ - float3 shadow; - - if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { - /* accumulate */ - path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); + } } } } @@ -86,15 +86,15 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobal light_t = 0.5f*light_t; LightSample ls; - light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls); + if(light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; - if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { - /* trace shadow ray */ - float3 shadow; - - if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { - /* accumulate */ - path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); + } } } } @@ -107,16 +107,16 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobal path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); LightSample ls; - light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls); + if(light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls)) { + /* sample random light */ + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; - /* sample random light */ - if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { - /* trace shadow ray */ - float3 shadow; - - if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { - /* accumulate */ - path_radiance_accum_light(L, throughput*num_samples_adjust, &L_light, shadow, num_samples_adjust, state->bounce, is_lamp); + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(L, throughput*num_samples_adjust, &L_light, shadow, num_samples_adjust, state->bounce, is_lamp); + } } } } @@ -206,15 +206,15 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, ccl_ #endif LightSample ls; - light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls); + if(light_sample(kg, light_t, light_u, light_v, ccl_fetch(sd, time), ccl_fetch(sd, P), state->bounce, &ls)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; - if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { - /* trace shadow ray */ - float3 shadow; - - if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { - /* accumulate */ - path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp); + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp); + } } } #endif diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h index 5fd4f2fad4c..0bb8f1c517f 100644 --- a/intern/cycles/kernel/kernel_path_volume.h +++ b/intern/cycles/kernel/kernel_path_volume.h @@ -46,17 +46,16 @@ ccl_device_inline void kernel_path_volume_connect_light( light_ray.time = sd->time; # endif - light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls); - if(ls.pdf == 0.0f) - return; - - if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { - /* trace shadow ray */ - float3 shadow; + if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) + { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; - if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { - /* accumulate */ - path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp); + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp); + } } } #endif @@ -146,7 +145,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); LightSample ls; - lamp_light_sample(kg, i, light_u, light_v, ray->P, &ls); + lamp_light_sample(kg, i, light_u, light_v, ray->P, &ls); float3 tp = throughput; @@ -156,23 +155,20 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false); - + (void)result; kernel_assert(result == VOLUME_PATH_SCATTERED); /* todo: split up light_sample so we don't have to call it again with new position */ - lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls); + if(lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; - if(ls.pdf == 0.0f) - continue; - - if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { - /* trace shadow ray */ - float3 shadow; - - if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { - /* accumulate */ - path_radiance_accum_light(L, tp*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(L, tp*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); + } } } } @@ -212,18 +208,15 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG kernel_assert(result == VOLUME_PATH_SCATTERED); /* todo: split up light_sample so we don't have to call it again with new position */ - light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls); + if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; - if(ls.pdf == 0.0f) - continue; - - if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { - /* trace shadow ray */ - float3 shadow; - - if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { - /* accumulate */ - path_radiance_accum_light(L, tp*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(L, tp*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); + } } } } @@ -251,19 +244,16 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG kernel_assert(result == VOLUME_PATH_SCATTERED); /* todo: split up light_sample so we don't have to call it again with new position */ - light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls); + if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { + /* sample random light */ + if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { + /* trace shadow ray */ + float3 shadow; - if(ls.pdf == 0.0f) - return; - - /* sample random light */ - if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp)) { - /* trace shadow ray */ - float3 shadow; - - if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { - /* accumulate */ - path_radiance_accum_light(L, tp, &L_light, shadow, 1.0f, state->bounce, is_lamp); + if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { + /* accumulate */ + path_radiance_accum_light(L, tp, &L_light, shadow, 1.0f, state->bounce, is_lamp); + } } } } diff --git a/intern/cycles/kernel/split/kernel_direct_lighting.h b/intern/cycles/kernel/split/kernel_direct_lighting.h index ebe91097496..6ad736fc2c1 100644 --- a/intern/cycles/kernel/split/kernel_direct_lighting.h +++ b/intern/cycles/kernel/split/kernel_direct_lighting.h @@ -74,30 +74,31 @@ ccl_device char kernel_direct_lighting( path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); LightSample ls; - light_sample(kg, - light_t, light_u, light_v, - ccl_fetch(sd, time), - ccl_fetch(sd, P), - state->bounce, - &ls); + if(light_sample(kg, + light_t, light_u, light_v, + ccl_fetch(sd, time), + ccl_fetch(sd, P), + state->bounce, + &ls)) { - Ray light_ray; + Ray light_ray; #ifdef __OBJECT_MOTION__ - light_ray.time = ccl_fetch(sd, time); + light_ray.time = ccl_fetch(sd, time); #endif - BsdfEval L_light; - bool is_lamp; - if(direct_emission(kg, sd, kg->sd_input, &ls, state, &light_ray, &L_light, &is_lamp)) { - /* Write intermediate data to global memory to access from - * the next kernel. - */ - LightRay_coop[ray_index] = light_ray; - BSDFEval_coop[ray_index] = L_light; - ISLamp_coop[ray_index] = is_lamp; - /* Mark ray state for next shadow kernel. */ - ADD_RAY_FLAG(ray_state, ray_index, RAY_SHADOW_RAY_CAST_DL); - enqueue_flag = 1; + BsdfEval L_light; + bool is_lamp; + if(direct_emission(kg, sd, kg->sd_input, &ls, state, &light_ray, &L_light, &is_lamp)) { + /* Write intermediate data to global memory to access from + * the next kernel. + */ + LightRay_coop[ray_index] = light_ray; + BSDFEval_coop[ray_index] = L_light; + ISLamp_coop[ray_index] = is_lamp; + /* Mark ray state for next shadow kernel. */ + ADD_RAY_FLAG(ray_state, ray_index, RAY_SHADOW_RAY_CAST_DL); + enqueue_flag = 1; + } } } #endif /* __EMISSION__ */