Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/kernel_path_branched.h')
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h133
1 files changed, 61 insertions, 72 deletions
diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h
index 10816d3e5d1..dde40674ee6 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -23,7 +23,6 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg,
ShaderData *emission_sd,
PathRadiance *L,
ccl_addr_space PathState *state,
- RNG *rng,
float3 throughput)
{
int num_samples = kernel_data.integrator.ao_samples;
@@ -35,7 +34,7 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg,
for(int j = 0; j < num_samples; j++) {
float bsdf_u, bsdf_v;
- path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
+ path_branched_rng_2D(kg, state->rng_hash, state, j, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
float3 ao_D;
float ao_pdf;
@@ -55,7 +54,7 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg,
light_ray.dP = sd->dP;
light_ray.dD = differential3_zero();
- if(!shadow_blocked(kg, emission_sd, state, &light_ray, &ao_shadow)) {
+ if(!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &ao_shadow)) {
path_radiance_accum_ao(L, state, throughput*num_samples_inv, ao_alpha, ao_bsdf, ao_shadow);
}
else {
@@ -69,7 +68,7 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg,
/* bounce off surface and integrate indirect light */
ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGlobals *kg,
- RNG *rng, ShaderData *sd, ShaderData *indirect_sd, ShaderData *emission_sd,
+ ShaderData *sd, ShaderData *indirect_sd, ShaderData *emission_sd,
float3 throughput, float num_samples_adjust, PathState *state, PathRadiance *L)
{
float sum_sample_weight = 0.0f;
@@ -113,15 +112,18 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba
num_samples = ceil_to_int(num_samples_adjust*num_samples);
float num_samples_inv = num_samples_adjust/num_samples;
- RNG bsdf_rng = cmj_hash(*rng, i);
for(int j = 0; j < num_samples; j++) {
PathState ps = *state;
float3 tp = throughput;
Ray bsdf_ray;
+#ifdef __SHADOW_TRICKS__
+ float shadow_transparency = L->shadow_transparency;
+#endif
+
+ ps.rng_hash = cmj_hash(state->rng_hash, i);
if(!kernel_branched_path_surface_bounce(kg,
- &bsdf_rng,
sd,
sc,
j,
@@ -135,10 +137,11 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba
continue;
}
+ ps.rng_hash = state->rng_hash;
+
kernel_path_indirect(kg,
indirect_sd,
emission_sd,
- rng,
&bsdf_ray,
tp*num_samples_inv,
num_samples,
@@ -149,6 +152,10 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba
* for the next samples */
path_radiance_sum_indirect(L);
path_radiance_reset_indirect(L);
+
+#ifdef __SHADOW_TRICKS__
+ L->shadow_transparency = shadow_transparency;
+#endif
}
}
}
@@ -160,7 +167,6 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
ShaderData *emission_sd,
PathRadiance *L,
PathState *state,
- RNG *rng,
Ray *ray,
float3 throughput)
{
@@ -171,17 +177,17 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
continue;
/* set up random number generator */
- uint lcg_state = lcg_state_init(rng, state->rng_offset, state->sample, 0x68bc21eb);
+ uint lcg_state = lcg_state_init(state, 0x68bc21eb);
int num_samples = kernel_data.integrator.subsurface_samples;
float num_samples_inv = 1.0f/num_samples;
- RNG bssrdf_rng = cmj_hash(*rng, i);
+ uint bssrdf_rng_hash = cmj_hash(state->rng_hash, i);
/* do subsurface scatter step with copy of shader data, this will
* replace the BSSRDF with a diffuse BSDF closure */
for(int j = 0; j < num_samples; j++) {
SubsurfaceIntersection ss_isect;
float bssrdf_u, bssrdf_v;
- path_branched_rng_2D(kg, &bssrdf_rng, state, j, num_samples, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
+ path_branched_rng_2D(kg, bssrdf_rng_hash, state, j, num_samples, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
int num_hits = subsurface_scatter_multi_intersect(kg,
&ss_isect,
sd,
@@ -234,7 +240,6 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
(state->flag & PATH_RAY_SHADOW_CATCHER);
kernel_branched_path_surface_connect_light(
kg,
- rng,
&bssrdf_sd,
emission_sd,
&hit_state,
@@ -248,7 +253,6 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
/* indirect light */
kernel_branched_path_surface_indirect_light(
kg,
- rng,
&bssrdf_sd,
indirect_sd,
emission_sd,
@@ -262,17 +266,16 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
}
#endif /* __SUBSURFACE__ */
-ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
- RNG *rng,
- int sample,
- Ray ray,
- ccl_global float *buffer,
- PathRadiance *L,
- bool *is_shadow_catcher)
+ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
+ uint rng_hash,
+ int sample,
+ Ray ray,
+ ccl_global float *buffer,
+ PathRadiance *L,
+ bool *is_shadow_catcher)
{
/* initialize */
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- float L_transparent = 0.0f;
path_radiance_init(L, kernel_data.film.use_light_pass);
@@ -282,12 +285,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
ShaderData emission_sd, indirect_sd;
PathState state;
- path_state_init(kg, &emission_sd, &state, rng, sample, &ray);
-
-#ifdef __KERNEL_DEBUG__
- DebugData debug_data;
- debug_data_init(&debug_data);
-#endif /* __KERNEL_DEBUG__ */
+ path_state_init(kg, &emission_sd, &state, rng_hash, sample, &ray);
/* Main Loop
* Here we only handle transparency intersections from the camera ray.
@@ -310,7 +308,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
}
extmax = kernel_data.curve.maximum_width;
- lcg_state = lcg_state_init(rng, state.rng_offset, state.sample, 0x51633e2d);
+ lcg_state = lcg_state_init(&state, 0x51633e2d);
}
bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax);
@@ -319,10 +317,10 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
#endif /* __HAIR__ */
#ifdef __KERNEL_DEBUG__
- debug_data.num_bvh_traversed_nodes += isect.num_traversed_nodes;
- debug_data.num_bvh_traversed_instances += isect.num_traversed_instances;
- debug_data.num_bvh_intersections += isect.num_intersections;
- debug_data.num_ray_bounces++;
+ 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;
+ L->debug_data.num_ray_bounces++;
#endif /* __KERNEL_DEBUG__ */
#ifdef __VOLUME__
@@ -353,7 +351,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
int all = kernel_data.integrator.sample_all_lights_direct;
- kernel_branched_path_volume_connect_light(kg, rng, &sd,
+ kernel_branched_path_volume_connect_light(kg, &sd,
&emission_sd, throughput, &state, L, all,
&volume_ray, &volume_segment);
@@ -372,8 +370,8 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
/* scatter sample. if we use distance sampling and take just one
* sample for direct and indirect light, we could share this
* computation, but makes code a bit complex */
- float rphase = path_state_rng_1D_for_decision(kg, rng, &ps, PRNG_PHASE);
- float rscatter = path_state_rng_1D_for_decision(kg, rng, &ps, PRNG_SCATTER_DISTANCE);
+ float rphase = path_state_rng_1D_for_decision(kg, &ps, PRNG_PHASE);
+ float rscatter = path_state_rng_1D_for_decision(kg, &ps, PRNG_SCATTER_DISTANCE);
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
&ps, &pray, &sd, &tp, rphase, rscatter, &volume_segment, NULL, false);
@@ -382,7 +380,6 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
kernel_assert(result == VOLUME_PATH_SCATTERED);
if(kernel_path_volume_bounce(kg,
- rng,
&sd,
&tp,
&ps,
@@ -392,7 +389,6 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
kernel_path_indirect(kg,
&indirect_sd,
&emission_sd,
- rng,
&pray,
tp*num_samples_inv,
num_samples,
@@ -431,16 +427,15 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
path_state_branch(&ps, j, num_samples);
VolumeIntegrateResult result = kernel_volume_integrate(
- kg, &ps, &sd, &volume_ray, L, &tp, rng, heterogeneous);
+ kg, &ps, &sd, &volume_ray, L, &tp, heterogeneous);
#ifdef __VOLUME_SCATTER__
if(result == VOLUME_PATH_SCATTERED) {
/* todo: support equiangular, MIS and all light sampling.
* alternatively get decoupled ray marching working on the GPU */
- kernel_path_volume_connect_light(kg, rng, &sd, &emission_sd, tp, &state, L);
+ kernel_path_volume_connect_light(kg, &sd, &emission_sd, tp, &state, L);
if(kernel_path_volume_bounce(kg,
- rng,
&sd,
&tp,
&ps,
@@ -450,7 +445,6 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
kernel_path_indirect(kg,
&indirect_sd,
&emission_sd,
- rng,
&pray,
tp,
num_samples,
@@ -475,7 +469,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
if(!hit) {
/* eval background shader if nothing hit */
if(kernel_data.background.transparent) {
- L_transparent += average(throughput);
+ L->transparent += average(throughput);
#ifdef __PASSES__
if(!(kernel_data.film.pass_flag & PASS_BACKGROUND))
@@ -494,21 +488,24 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
/* setup shading */
shader_setup_from_ray(kg, &sd, &isect, &ray);
- shader_eval_surface(kg, &sd, rng, &state, 0.0f, state.flag, SHADER_CONTEXT_MAIN);
+ shader_eval_surface(kg, &sd, &state, 0.0f, state.flag);
shader_merge_closures(&sd);
#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 | PATH_RAY_STORE_SHADOW_INFO);
- state.catcher_object = sd.object;
- if(!kernel_data.background.transparent) {
- L->shadow_color = indirect_background(kg, &emission_sd, &state, &ray);
- }
+ state.flag |= (PATH_RAY_SHADOW_CATCHER |
+ PATH_RAY_STORE_SHADOW_INFO);
+ if(!kernel_data.background.transparent) {
+ L->shadow_background_color =
+ indirect_background(kg, &emission_sd, &state, &ray);
}
+ L->shadow_radiance_sum = path_radiance_clamp_and_sum(kg, L);
+ L->shadow_throughput = average(throughput);
}
- else {
- state.flag &= ~PATH_RAY_SHADOW_CATCHER_ONLY;
+ else if(state.flag & PATH_RAY_SHADOW_CATCHER) {
+ /* Only update transparency after shadow catcher bounce. */
+ L->shadow_transparency *=
+ average(shader_bsdf_transparency(kg, &sd));
}
#endif /* __SHADOW_TRICKS__ */
@@ -524,7 +521,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
holdout_weight = shader_holdout_eval(kg, &sd);
}
/* any throughput is ok, should all be identical here */
- L_transparent += average(holdout_weight*throughput);
+ L->transparent += average(holdout_weight*throughput);
}
if(sd.object_flag & SD_OBJECT_HOLDOUT_MASK) {
break;
@@ -548,13 +545,13 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
/* path termination. this is a strange place to put the termination, it's
* mainly due to the mixed in MIS that we use. gives too many unneeded
* shader evaluations, only need emission if we are going to terminate */
- float probability = path_state_terminate_probability(kg, &state, throughput);
+ float probability = path_state_continuation_probability(kg, &state, throughput);
if(probability == 0.0f) {
break;
}
else if(probability != 1.0f) {
- float terminate = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_TERMINATE);
+ float terminate = path_state_rng_1D_for_decision(kg, &state, PRNG_TERMINATE);
if(terminate >= probability)
break;
@@ -568,7 +565,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
#ifdef __AO__
/* ambient occlusion */
if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) {
- kernel_branched_path_ao(kg, &sd, &emission_sd, L, &state, rng, throughput);
+ kernel_branched_path_ao(kg, &sd, &emission_sd, L, &state, throughput);
}
#endif /* __AO__ */
@@ -576,7 +573,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
/* bssrdf scatter to a different location on the same object */
if(sd.flag & SD_BSSRDF) {
kernel_branched_path_subsurface_scatter(kg, &sd, &indirect_sd, &emission_sd,
- L, &state, rng, &ray, throughput);
+ L, &state, &ray, throughput);
}
#endif /* __SUBSURFACE__ */
@@ -588,13 +585,13 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
if(kernel_data.integrator.use_direct_light) {
int all = (kernel_data.integrator.sample_all_lights_direct) ||
(state.flag & PATH_RAY_SHADOW_CATCHER);
- kernel_branched_path_surface_connect_light(kg, rng,
+ kernel_branched_path_surface_connect_light(kg,
&sd, &emission_sd, &hit_state, throughput, 1.0f, L, all);
}
#endif /* __EMISSION__ */
/* indirect light */
- kernel_branched_path_surface_indirect_light(kg, rng,
+ kernel_branched_path_surface_indirect_light(kg,
&sd, &indirect_sd, &emission_sd, throughput, 1.0f, &hit_state, L);
/* continue in case of transparency */
@@ -625,14 +622,8 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
}
#ifdef __SHADOW_TRICKS__
- *is_shadow_catcher = (state.flag & PATH_RAY_SHADOW_CATCHER);
+ *is_shadow_catcher = (state.flag & PATH_RAY_SHADOW_CATCHER) != 0;
#endif /* __SHADOW_TRICKS__ */
-
-#ifdef __KERNEL_DEBUG__
- kernel_write_debug_passes(kg, buffer, &state, &debug_data, sample);
-#endif /* __KERNEL_DEBUG__ */
-
- return 1.0f - L_transparent;
}
ccl_device void kernel_branched_path_trace(KernelGlobals *kg,
@@ -647,24 +638,22 @@ ccl_device void kernel_branched_path_trace(KernelGlobals *kg,
buffer += index*pass_stride;
/* initialize random numbers and ray */
- RNG rng;
+ uint rng_hash;
Ray ray;
- kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng, &ray);
+ kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng_hash, &ray);
/* integrate */
PathRadiance L;
bool is_shadow_catcher;
if(ray.t != 0.0f) {
- float alpha = kernel_branched_path_integrate(kg, &rng, sample, ray, buffer, &L, &is_shadow_catcher);
- kernel_write_result(kg, buffer, sample, &L, alpha, is_shadow_catcher);
+ kernel_branched_path_integrate(kg, rng_hash, sample, ray, buffer, &L, &is_shadow_catcher);
+ kernel_write_result(kg, buffer, sample, &L, is_shadow_catcher);
}
else {
- kernel_write_result(kg, buffer, sample, NULL, 0.0f, false);
+ kernel_write_result(kg, buffer, sample, NULL, false);
}
-
- path_rng_end(kg, rng_state, rng);
}
#endif /* __SPLIT_KERNEL__ */