diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-02-09 16:19:01 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-03-27 11:46:03 +0300 |
commit | d14e39622ae627c1a4329e630715c5197c762493 (patch) | |
tree | d246f7083bcc82236488d5aaec25cb2e735c4145 /intern/cycles/kernel/kernel_path.h | |
parent | 5aaa643947929cf807c349b2b5fe33d4dc669c3d (diff) |
Cycles: First implementation of shadow catcher
It uses an idea of accumulating all possible light reachable across the
light path (without taking shadow blocked into account) and accumulating
total shaded light across the path. Dividing second figure by first one
seems to be giving good estimate of the shadow.
In fact, to my knowledge, it's something really similar to what is
happening in the denoising branch, so we are aligned here which is good.
The workflow is following:
- Create an object which matches real-life object on which shadow is
to be catched.
- Create approximate similar material on that object.
This is needed to make indirect light properly affecting CG objects
in the scene.
- Mark object as Shadow Catcher in the Object properties.
Ideally, after doing that it will be possible to render the image and
simply alpha-over it on top of real footage.
Diffstat (limited to 'intern/cycles/kernel/kernel_path.h')
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index ebf03ad9778..74631aa98cf 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -92,6 +92,9 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg, if(!shadow_blocked(kg, emission_sd, state, &light_ray, &ao_shadow)) { path_radiance_accum_ao(L, throughput, ao_alpha, ao_bsdf, ao_shadow, state->bounce); } + else { + path_radiance_accum_total_ao(L, throughput, ao_bsdf); + } } } @@ -290,9 +293,9 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, /* sample background shader */ float3 L_background = indirect_background(kg, emission_sd, state, ray); path_radiance_accum_background(L, + state, throughput, - L_background, - state->bounce); + L_background); #endif /* __BACKGROUND__ */ break; @@ -312,6 +315,12 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, shader_merge_closures(sd); #endif /* __BRANCHED_PATH__ */ +#ifdef __SHADOW_TRICKS__ + if(!(sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) { + state->flag &= ~PATH_RAY_SHADOW_CATCHER_ONLY; + } +#endif /* __SHADOW_TRICKS__ */ + /* blurring of bsdf after bounces, for rays that have a small likelihood * of following this particular path (diffuse, rough glossy) */ if(kernel_data.integrator.filter_glossy != FLT_MAX) { @@ -396,7 +405,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, #if defined(__EMISSION__) && defined(__BRANCHED_PATH__) if(kernel_data.integrator.use_direct_light) { - int all = kernel_data.integrator.sample_all_lights_indirect; + int all = (kernel_data.integrator.sample_all_lights_indirect) || + (state->flag & PATH_RAY_SHADOW_CATCHER); kernel_branched_path_surface_connect_light(kg, rng, sd, @@ -611,7 +621,7 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, #ifdef __BACKGROUND__ /* sample background shader */ float3 L_background = indirect_background(kg, &emission_sd, &state, &ray); - path_radiance_accum_background(&L, throughput, L_background, state.bounce); + path_radiance_accum_background(&L, &state, throughput, L_background); #endif /* __BACKGROUND__ */ break; @@ -625,6 +635,21 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, float rbsdf = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_BSDF); shader_eval_surface(kg, &sd, rng, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN); +#ifdef __SHADOW_TRICKS__ + if((sd.object_flag & SD_OBJECT_SHADOW_CATCHER)) { + if(state.flag & PATH_RAY_CAMERA) { + state.flag |= (PATH_RAY_SHADOW_CATCHER | PATH_RAY_SHADOW_CATCHER_ONLY); + state.catcher_object = sd.object; + if(!kernel_data.background.transparent) { + L.shadow_color = indirect_background(kg, &emission_sd, &state, &ray); + } + } + } + else { + state.flag &= ~PATH_RAY_SHADOW_CATCHER_ONLY; + } +#endif /* __SHADOW_TRICKS__ */ + /* holdout */ #ifdef __HOLDOUT__ if(((sd.flag & SD_HOLDOUT) || @@ -742,7 +767,16 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg, } #endif /* __SUBSURFACE__ */ - float3 L_sum = path_radiance_clamp_and_sum(kg, &L); + float3 L_sum; +#ifdef __SHADOW_TRICKS__ + if(state.flag & PATH_RAY_SHADOW_CATCHER) { + L_sum = path_radiance_sum_shadowcatcher(kg, &L, &L_transparent); + } + else +#endif /* __SHADOW_TRICKS__ */ + { + L_sum = path_radiance_clamp_and_sum(kg, &L); + } kernel_write_light_passes(kg, buffer, &L, sample); |