diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2014-05-07 18:55:09 +0400 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2014-05-07 18:59:25 +0400 |
commit | 83cdd5887f10e1998a434fb1632e0b76ec938d91 (patch) | |
tree | a4ac46fb7a604d09c089bd1b5c460eed29696556 /intern/cycles/kernel | |
parent | 3fbc984b069fed441cccdd3416ec71e064235e36 (diff) |
Cycles-Bake: Subsurface Scattering support (fix T40060)
This fixes the SSS Direct/Indirect passes as well as the Combined pass.
Patch reviewed and with fixes and contributions from Brecht van Lommel.
Note: displacement/bump map (related to the report) will be handled separately
Reviewers: brecht
Differential Revision: https://developer.blender.org/D503
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r-- | intern/cycles/kernel/kernel_displace.h | 18 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 85 |
2 files changed, 61 insertions, 42 deletions
diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h index 012f399ca50..e54a16ac118 100644 --- a/intern/cycles/kernel/kernel_displace.h +++ b/intern/cycles/kernel/kernel_displace.h @@ -17,7 +17,7 @@ CCL_NAMESPACE_BEGIN ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, RNG rng, - bool is_combined, bool is_ao) + bool is_combined, bool is_ao, bool is_sss) { int samples = kernel_data.integrator.aa_samples; @@ -50,13 +50,21 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian kernel_path_ao(kg, sd, &L_sample, &state, &rng, throughput); } + /* sample subsurface scattering */ + if((is_combined || is_sss) && (sd->flag & SD_BSSRDF)) { +#ifdef __SUBSURFACE__ + /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */ + if (kernel_path_subsurface_scatter(kg, sd, &L_sample, &state, &rng, &ray, &throughput)) + is_sss = true; +#endif + } + /* sample light and BSDF */ - if(!is_ao) { + if((!is_sss) && (!is_ao)) { if(kernel_path_integrate_lighting(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) { #ifdef __LAMP_MIS__ state.ray_t = 0.0f; #endif - /* compute indirect light */ kernel_path_indirect(kg, &rng, ray, throughput, state.num_samples, state, &L_sample); @@ -127,7 +135,9 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, if(is_light_pass(type)) { RNG rng = cmj_hash(i, 0); compute_light_pass(kg, &sd, &L, rng, (type == SHADER_EVAL_COMBINED), - (type == SHADER_EVAL_AO)); + (type == SHADER_EVAL_AO), + (type == SHADER_EVAL_SUBSURFACE_DIRECT || + type == SHADER_EVAL_SUBSURFACE_INDIRECT)); } switch (type) { diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index bd7b53e3aec..a80a0033712 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -601,6 +601,52 @@ ccl_device void kernel_path_ao(KernelGlobals *kg, ShaderData *sd, PathRadiance * } } +#ifdef __SUBSURFACE__ +ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, PathState *state, RNG *rng, Ray *ray, float3 *throughput) +{ + float bssrdf_probability; + ShaderClosure *sc = subsurface_scatter_pick_closure(kg, sd, &bssrdf_probability); + + /* modify throughput for picking bssrdf or bsdf */ + *throughput *= bssrdf_probability; + + /* do bssrdf scatter step if we picked a bssrdf closure */ + if(sc) { + uint lcg_state = lcg_state_init(rng, state, 0x68bc21eb); + + ShaderData bssrdf_sd[BSSRDF_MAX_HITS]; + float bssrdf_u, bssrdf_v; + path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); + int num_hits = subsurface_scatter_multi_step(kg, sd, bssrdf_sd, state->flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false); + + /* compute lighting with the BSDF closure */ + for(int hit = 0; hit < num_hits; hit++) { + float3 tp = *throughput; + PathState hit_state = *state; + Ray hit_ray = *ray; + + hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR; + hit_state.rng_offset += PRNG_BOUNCE_NUM; + + if(kernel_path_integrate_lighting(kg, rng, &bssrdf_sd[hit], &tp, &hit_state, L, &hit_ray)) { +#ifdef __LAMP_MIS__ + hit_state.ray_t = 0.0f; +#endif + + kernel_path_indirect(kg, rng, hit_ray, tp, state->num_samples, hit_state, L); + + /* for render passes, sum and reset indirect light pass variables + * for the next samples */ + path_radiance_sum_indirect(L); + path_radiance_reset_indirect(L); + } + } + return true; + } + return false; +} +#endif + ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, ccl_global float *buffer) { /* initialize */ @@ -776,45 +822,8 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, /* bssrdf scatter to a different location on the same object, replacing * the closures with a diffuse BSDF */ if(sd.flag & SD_BSSRDF) { - float bssrdf_probability; - ShaderClosure *sc = subsurface_scatter_pick_closure(kg, &sd, &bssrdf_probability); - - /* modify throughput for picking bssrdf or bsdf */ - throughput *= bssrdf_probability; - - /* do bssrdf scatter step if we picked a bssrdf closure */ - if(sc) { - uint lcg_state = lcg_state_init(rng, &state, 0x68bc21eb); - - ShaderData bssrdf_sd[BSSRDF_MAX_HITS]; - float bssrdf_u, bssrdf_v; - path_state_rng_2D(kg, rng, &state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); - int num_hits = subsurface_scatter_multi_step(kg, &sd, bssrdf_sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false); - - /* compute lighting with the BSDF closure */ - for(int hit = 0; hit < num_hits; hit++) { - float3 tp = throughput; - PathState hit_state = state; - Ray hit_ray = ray; - - hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR; - hit_state.rng_offset += PRNG_BOUNCE_NUM; - - if(kernel_path_integrate_lighting(kg, rng, &bssrdf_sd[hit], &tp, &hit_state, &L, &hit_ray)) { -#ifdef __LAMP_MIS__ - hit_state.ray_t = 0.0f; -#endif - - kernel_path_indirect(kg, rng, hit_ray, tp, state.num_samples, hit_state, &L); - - /* for render passes, sum and reset indirect light pass variables - * for the next samples */ - path_radiance_sum_indirect(&L); - path_radiance_reset_indirect(&L); - } - } + if(kernel_path_subsurface_scatter(kg, &sd, &L, &state, rng, &ray, &throughput)) break; - } } #endif |