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
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2017-09-13 03:10:24 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2017-09-13 16:24:14 +0300
commitf77cdd1d59f6e895b567c4d5fdcc6f2440e03307 (patch)
tree2e275e1fc3c6348aa9907b62cc943a0eb0cc36d3 /intern
parentc4c450045d072c79d02a1857f56ecf94689375c8 (diff)
Code cleanup: deduplicate some branched and split kernel code.
Benchmarks peformance on GTX 1080 and RX 480 on Linux is the same for bmw27, classroom, pabellon, and about 2% faster on fishy_cat and koro.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/kernel_emission.h2
-rw-r--r--intern/cycles/kernel/kernel_passes.h3
-rw-r--r--intern/cycles/kernel/kernel_path.h806
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h111
-rw-r--r--intern/cycles/kernel/kernel_path_volume.h4
-rw-r--r--intern/cycles/kernel/kernel_shader.h10
-rw-r--r--intern/cycles/kernel/split/kernel_direct_lighting.h2
-rw-r--r--intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h112
-rw-r--r--intern/cycles/kernel/split/kernel_indirect_background.h30
-rw-r--r--intern/cycles/kernel/split/kernel_lamp_emission.h23
-rw-r--r--intern/cycles/kernel/split/kernel_scene_intersect.h46
11 files changed, 409 insertions, 740 deletions
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 48a8e53be33..13d4759a9ec 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -37,9 +37,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
ray.D = ls->D;
ray.P = ls->P;
ray.t = 1.0f;
-# ifdef __OBJECT_MOTION__
ray.time = time;
-# endif
ray.dP = differential3_zero();
ray.dD = dI;
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index d454cce6e30..06510442cd1 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -225,7 +225,7 @@ ccl_device_inline void kernel_write_debug_passes(KernelGlobals *kg,
#endif /* __KERNEL_DEBUG__ */
ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global float *buffer, PathRadiance *L,
- ShaderData *sd, int sample, ccl_addr_space PathState *state, float3 throughput)
+ ShaderData *sd, ccl_addr_space PathState *state, float3 throughput)
{
#ifdef __PASSES__
int path_flag = state->flag;
@@ -243,6 +243,7 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global fl
kernel_data.film.pass_alpha_threshold == 0.0f ||
average(shader_bsdf_alpha(kg, sd)) >= kernel_data.film.pass_alpha_threshold)
{
+ int sample = state->sample;
if(sample == 0) {
if(flag & PASS_DEPTH) {
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index bfde96ec270..afaa47c768c 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -50,6 +50,294 @@
CCL_NAMESPACE_BEGIN
+ccl_device_forceinline bool kernel_path_scene_intersect(
+ KernelGlobals *kg,
+ ccl_addr_space PathState *state,
+ Ray *ray,
+ Intersection *isect,
+ PathRadiance *L)
+{
+ uint visibility = path_state_ray_visibility(kg, state);
+
+#ifdef __HAIR__
+ float difl = 0.0f, extmax = 0.0f;
+ uint lcg_state = 0;
+
+ if(kernel_data.bvh.have_curves) {
+ 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_addrspace(state, 0x51633e2d);
+ }
+
+ 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
+ bool hit = scene_intersect(kg, *ray, visibility, isect, NULL, 0.0f, 0.0f);
+#endif /* __HAIR__ */
+
+#ifdef __KERNEL_DEBUG__
+ 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;
+ }
+ L->debug_data.num_ray_bounces++;
+#endif /* __KERNEL_DEBUG__ */
+
+ return hit;
+}
+
+ccl_device_forceinline void kernel_path_lamp_emission(
+ KernelGlobals *kg,
+ ccl_addr_space PathState *state,
+ Ray *ray,
+ float3 throughput,
+ ccl_addr_space Intersection *isect,
+ ShaderData *emission_sd,
+ PathRadiance *L)
+{
+#ifdef __LAMP_MIS__
+ if(kernel_data.integrator.use_lamp_mis && !(state->flag & PATH_RAY_CAMERA)) {
+ /* ray starting from previous non-transparent bounce */
+ Ray light_ray;
+
+ light_ray.P = ray->P - state->ray_t*ray->D;
+ state->ray_t += isect->t;
+ light_ray.D = ray->D;
+ light_ray.t = state->ray_t;
+ light_ray.time = ray->time;
+ light_ray.dD = ray->dD;
+ light_ray.dP = ray->dP;
+
+ /* intersect with lamp */
+ float3 emission;
+
+ if(indirect_lamp_emission(kg, emission_sd, state, &light_ray, &emission))
+ path_radiance_accum_emission(L, throughput, emission, state->bounce);
+ }
+#endif /* __LAMP_MIS__ */
+}
+
+ccl_device_forceinline void kernel_path_background(
+ KernelGlobals *kg,
+ ccl_addr_space PathState *state,
+ ccl_addr_space Ray *ray,
+ float3 throughput,
+ ShaderData *emission_sd,
+ PathRadiance *L)
+{
+ /* eval background shader if nothing hit */
+ if(kernel_data.background.transparent && (state->flag & PATH_RAY_CAMERA)) {
+ L->transparent += average(throughput);
+
+#ifdef __PASSES__
+ if(!(kernel_data.film.pass_flag & PASS_BACKGROUND))
+#endif /* __PASSES__ */
+ return;
+ }
+
+#ifdef __BACKGROUND__
+ /* sample background shader */
+ float3 L_background = indirect_background(kg, emission_sd, state, ray);
+ path_radiance_accum_background(L, state, throughput, L_background);
+#endif /* __BACKGROUND__ */
+}
+
+#ifndef __SPLIT_KERNEL__
+
+ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(
+ KernelGlobals *kg,
+ ShaderData *sd,
+ PathState *state,
+ Ray *ray,
+ float3 *throughput,
+ ccl_addr_space Intersection *isect,
+ bool hit,
+ ShaderData *emission_sd,
+ PathRadiance *L)
+{
+#ifdef __VOLUME__
+ /* Sanitize volume stack. */
+ if(!hit) {
+ kernel_volume_clean_stack(kg, state->volume_stack);
+ }
+ /* volume attenuation, emission, scatter */
+ if(state->volume_stack[0].shader != SHADER_NONE) {
+ Ray volume_ray = *ray;
+ volume_ray.t = (hit)? isect->t: FLT_MAX;
+
+ bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
+
+# ifdef __VOLUME_DECOUPLED__
+ int sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
+ bool direct = (state->flag & PATH_RAY_CAMERA) != 0;
+ bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, direct, sampling_method);
+
+ if(decoupled) {
+ /* cache steps along volume for repeated sampling */
+ VolumeSegment volume_segment;
+
+ shader_setup_from_volume(kg, sd, &volume_ray);
+ kernel_volume_decoupled_record(kg, state,
+ &volume_ray, sd, &volume_segment, heterogeneous);
+
+ volume_segment.sampling_method = sampling_method;
+
+ /* emission */
+ if(volume_segment.closure_flag & SD_EMISSION)
+ path_radiance_accum_emission(L, *throughput, volume_segment.accum_emission, state->bounce);
+
+ /* scattering */
+ VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED;
+
+ if(volume_segment.closure_flag & SD_SCATTER) {
+ int all = kernel_data.integrator.sample_all_lights_indirect;
+
+ /* direct light sampling */
+ kernel_branched_path_volume_connect_light(kg, sd,
+ emission_sd, *throughput, state, L, all,
+ &volume_ray, &volume_segment);
+
+ /* indirect 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, state, PRNG_PHASE);
+ float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
+
+ result = kernel_volume_decoupled_scatter(kg,
+ state, &volume_ray, sd, throughput,
+ rphase, rscatter, &volume_segment, NULL, true);
+ }
+
+ /* free cached steps */
+ kernel_volume_decoupled_free(kg, &volume_segment);
+
+ if(result == VOLUME_PATH_SCATTERED) {
+ if(kernel_path_volume_bounce(kg, sd, throughput, state, L, ray))
+ return VOLUME_PATH_SCATTERED;
+ else
+ return VOLUME_PATH_MISSED;
+ }
+ else {
+ *throughput *= volume_segment.accum_transmittance;
+ }
+ }
+ else
+# endif /* __VOLUME_DECOUPLED__ */
+ {
+ /* integrate along volume segment with distance sampling */
+ VolumeIntegrateResult result = kernel_volume_integrate(
+ kg, state, sd, &volume_ray, L, throughput, heterogeneous);
+
+# ifdef __VOLUME_SCATTER__
+ if(result == VOLUME_PATH_SCATTERED) {
+ /* direct lighting */
+ kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L);
+
+ /* indirect light bounce */
+ if(kernel_path_volume_bounce(kg, sd, throughput, state, L, ray))
+ return VOLUME_PATH_SCATTERED;
+ else
+ return VOLUME_PATH_MISSED;
+ }
+# endif /* __VOLUME_SCATTER__ */
+ }
+ }
+#endif /* __VOLUME__ */
+
+ return VOLUME_PATH_ATTENUATED;
+}
+
+#endif /* __SPLIT_KERNEL__ */
+
+ccl_device_forceinline bool kernel_path_shader_apply(
+ KernelGlobals *kg,
+ ShaderData *sd,
+ ccl_addr_space PathState *state,
+ ccl_addr_space Ray *ray,
+ float3 throughput,
+ ShaderData *emission_sd,
+ PathRadiance *L,
+ ccl_global float *buffer)
+{
+#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_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 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__ */
+
+ /* holdout */
+#ifdef __HOLDOUT__
+ if(((sd->flag & SD_HOLDOUT) ||
+ (sd->object_flag & SD_OBJECT_HOLDOUT_MASK)) &&
+ (state->flag & PATH_RAY_CAMERA))
+ {
+ if(kernel_data.background.transparent) {
+ float3 holdout_weight;
+ if(sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
+ holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
+ }
+ else {
+ holdout_weight = shader_holdout_eval(kg, sd);
+ }
+ /* any throughput is ok, should all be identical here */
+ L->transparent += average(holdout_weight*throughput);
+ }
+
+ if(sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
+ return false;
+ }
+ }
+#endif /* __HOLDOUT__ */
+
+ /* holdout mask objects do not write data passes */
+ kernel_write_data_passes(kg, buffer, L, sd, state, throughput);
+
+ /* 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) {
+ float blur_pdf = kernel_data.integrator.filter_glossy*state->min_ray_pdf;
+
+ if(blur_pdf < 1.0f) {
+ float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f;
+ shader_bsdf_blur(kg, sd, blur_roughness);
+ }
+ }
+
+#ifdef __EMISSION__
+ /* emission */
+ if(sd->flag & SD_EMISSION) {
+ float3 emission = indirect_primitive_emission(kg, sd, sd->ray_length, state->flag, state->ray_pdf);
+ path_radiance_accum_emission(L, throughput, emission, state->bounce);
+ }
+#endif /* __EMISSION__ */
+
+ return true;
+}
+
ccl_device_noinline void kernel_path_ao(KernelGlobals *kg,
ShaderData *sd,
ShaderData *emission_sd,
@@ -78,9 +366,7 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg,
light_ray.P = ray_offset(sd->P, sd->Ng);
light_ray.D = ao_D;
light_ray.t = kernel_data.background.ao_distance;
-#ifdef __OBJECT_MOTION__
light_ray.time = sd->time;
-#endif /* __OBJECT_MOTION__ */
light_ray.dP = sd->dP;
light_ray.dD = differential3_zero();
@@ -108,197 +394,41 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
{
/* path iteration */
for(;;) {
- /* intersect scene */
+ /* Find intersection with objects in scene. */
Intersection isect;
- uint visibility = path_state_ray_visibility(kg, state);
- 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);
-
-#ifdef __LAMP_MIS__
- if(kernel_data.integrator.use_lamp_mis && !(state->flag & PATH_RAY_CAMERA)) {
- /* ray starting from previous non-transparent bounce */
- Ray light_ray;
-
- light_ray.P = ray->P - state->ray_t*ray->D;
- state->ray_t += isect.t;
- light_ray.D = ray->D;
- light_ray.t = state->ray_t;
- light_ray.time = ray->time;
- light_ray.dD = ray->dD;
- light_ray.dP = ray->dP;
-
- /* intersect with lamp */
- float3 emission;
- if(indirect_lamp_emission(kg, emission_sd, state, &light_ray, &emission)) {
- path_radiance_accum_emission(L,
- throughput,
- emission,
- state->bounce);
- }
- }
-#endif /* __LAMP_MIS__ */
-
-#ifdef __VOLUME__
- /* Sanitize volume stack. */
- if(!hit) {
- kernel_volume_clean_stack(kg, state->volume_stack);
- }
- /* volume attenuation, emission, scatter */
- if(state->volume_stack[0].shader != SHADER_NONE) {
- Ray volume_ray = *ray;
- volume_ray.t = (hit)? isect.t: FLT_MAX;
-
- bool heterogeneous =
- volume_stack_is_heterogeneous(kg,
- state->volume_stack);
-
-# ifdef __VOLUME_DECOUPLED__
- int sampling_method =
- volume_stack_sampling_method(kg,
- state->volume_stack);
- bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, false, sampling_method);
-
- if(decoupled) {
- /* cache steps along volume for repeated sampling */
- VolumeSegment volume_segment;
-
- shader_setup_from_volume(kg,
- sd,
- &volume_ray);
- kernel_volume_decoupled_record(kg,
- state,
- &volume_ray,
- sd,
- &volume_segment,
- heterogeneous);
-
- volume_segment.sampling_method = sampling_method;
-
- /* emission */
- if(volume_segment.closure_flag & SD_EMISSION) {
- path_radiance_accum_emission(L,
- throughput,
- volume_segment.accum_emission,
- state->bounce);
- }
-
- /* scattering */
- VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED;
-
- if(volume_segment.closure_flag & SD_SCATTER) {
- int all = kernel_data.integrator.sample_all_lights_indirect;
-
- /* direct light sampling */
- kernel_branched_path_volume_connect_light(kg,
- sd,
- emission_sd,
- throughput,
- state,
- L,
- all,
- &volume_ray,
- &volume_segment);
-
- /* indirect 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, state, PRNG_PHASE);
- float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
-
- result = kernel_volume_decoupled_scatter(kg,
- state,
- &volume_ray,
- sd,
- &throughput,
- rphase,
- rscatter,
- &volume_segment,
- NULL,
- true);
- }
-
- /* free cached steps */
- kernel_volume_decoupled_free(kg, &volume_segment);
-
- if(result == VOLUME_PATH_SCATTERED) {
- if(kernel_path_volume_bounce(kg,
- sd,
- &throughput,
- state,
- L,
- ray))
- {
- continue;
- }
- else {
- break;
- }
- }
- else {
- throughput *= volume_segment.accum_transmittance;
- }
- }
- else
-# endif /* __VOLUME_DECOUPLED__ */
- {
- /* integrate along volume segment with distance sampling */
- VolumeIntegrateResult result = kernel_volume_integrate(
- kg, state, sd, &volume_ray, L, &throughput, heterogeneous);
-
-# ifdef __VOLUME_SCATTER__
- if(result == VOLUME_PATH_SCATTERED) {
- /* direct lighting */
- kernel_path_volume_connect_light(kg,
- sd,
- emission_sd,
- throughput,
- state,
- L);
-
- /* indirect light bounce */
- if(kernel_path_volume_bounce(kg,
- sd,
- &throughput,
- state,
- L,
- ray))
- {
- continue;
- }
- else {
- break;
- }
- }
-# endif /* __VOLUME_SCATTER__ */
- }
+ bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
+
+ /* Find intersection with lamps and compute emission for MIS. */
+ kernel_path_lamp_emission(kg, state, ray, throughput, &isect, emission_sd, L);
+
+ /* Volume integration. */
+ VolumeIntegrateResult result = kernel_path_volume(kg,
+ sd,
+ state,
+ ray,
+ &throughput,
+ &isect,
+ hit,
+ emission_sd,
+ L);
+
+ if(result == VOLUME_PATH_SCATTERED) {
+ continue;
+ }
+ else if(result == VOLUME_PATH_MISSED) {
+ break;
}
-#endif /* __VOLUME__ */
+ /* Shade background. */
if(!hit) {
-#ifdef __BACKGROUND__
- /* sample background shader */
- float3 L_background = indirect_background(kg, emission_sd, state, ray);
- path_radiance_accum_background(L,
- state,
- throughput,
- L_background);
-#endif /* __BACKGROUND__ */
-
+ kernel_path_background(kg, state, ray, throughput, emission_sd, L);
break;
}
- else if(path_state_ao_bounce(kg, state)) {
+ else if(path_state_ao_bounce(kg, state)) {
break;
}
- /* setup shading */
+ /* Setup and evaluate shader. */
shader_setup_from_ray(kg,
sd,
&isect,
@@ -309,38 +439,18 @@ 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))
+ /* Apply shadow catcher, holdout, emission. */
+ if(!kernel_path_shader_apply(kg,
+ sd,
+ state,
+ ray,
+ throughput,
+ emission_sd,
+ L,
+ NULL))
{
- /* Only update transparency after shadow catcher bounce. */
- L->shadow_transparency *=
- average(shader_bsdf_transparency(kg, sd));
- }
-#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) {
- float blur_pdf = kernel_data.integrator.filter_glossy*state->min_ray_pdf;
-
- if(blur_pdf < 1.0f) {
- float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f;
- shader_bsdf_blur(kg, sd, blur_roughness);
- }
- }
-
-#ifdef __EMISSION__
- /* emission */
- if(sd->flag & SD_EMISSION) {
- float3 emission = indirect_primitive_emission(kg,
- sd,
- isect.t,
- state->flag,
- state->ray_pdf);
- path_radiance_accum_emission(L, throughput, emission, state->bounce);
+ break;
}
-#endif /* __EMISSION__ */
/* 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
@@ -430,7 +540,7 @@ ccl_device_forceinline void kernel_path_integrate(
float3 throughput,
Ray *ray,
PathRadiance *L,
- float *buffer,
+ ccl_global float *buffer,
ShaderData *emission_sd,
bool *is_shadow_catcher)
{
@@ -446,252 +556,57 @@ ccl_device_forceinline void kernel_path_integrate(
/* path iteration */
for(;;) {
- /* intersect scene */
+ /* Find intersection with objects in scene. */
Intersection isect;
- uint visibility = path_state_ray_visibility(kg, state);
-
-#ifdef __HAIR__
- float difl = 0.0f, extmax = 0.0f;
- uint lcg_state = 0;
-
- if(kernel_data.bvh.have_curves) {
- 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);
- }
-
- 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__ */
-
-#ifdef __KERNEL_DEBUG__
- 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;
- }
- L->debug_data.num_ray_bounces++;
-#endif /* __KERNEL_DEBUG__ */
-
-#ifdef __LAMP_MIS__
- if(kernel_data.integrator.use_lamp_mis && !(state->flag & PATH_RAY_CAMERA)) {
- /* ray starting from previous non-transparent bounce */
- Ray light_ray;
-
- light_ray.P = ray->P - state->ray_t*ray->D;
- state->ray_t += isect.t;
- light_ray.D = ray->D;
- light_ray.t = state->ray_t;
- light_ray.time = ray->time;
- light_ray.dD = ray->dD;
- light_ray.dP = ray->dP;
-
- /* intersect with lamp */
- float3 emission;
-
- if(indirect_lamp_emission(kg, emission_sd, state, &light_ray, &emission))
- path_radiance_accum_emission(L, throughput, emission, state->bounce);
- }
-#endif /* __LAMP_MIS__ */
-
-#ifdef __VOLUME__
- /* Sanitize volume stack. */
- if(!hit) {
- kernel_volume_clean_stack(kg, state->volume_stack);
- }
- /* volume attenuation, emission, scatter */
- if(state->volume_stack[0].shader != SHADER_NONE) {
- Ray volume_ray = *ray;
- volume_ray.t = (hit)? isect.t: FLT_MAX;
-
- bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
-
-# ifdef __VOLUME_DECOUPLED__
- int sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
- bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, true, sampling_method);
-
- if(decoupled) {
- /* cache steps along volume for repeated sampling */
- VolumeSegment volume_segment;
-
- shader_setup_from_volume(kg, &sd, &volume_ray);
- kernel_volume_decoupled_record(kg, state,
- &volume_ray, &sd, &volume_segment, heterogeneous);
-
- volume_segment.sampling_method = sampling_method;
-
- /* emission */
- if(volume_segment.closure_flag & SD_EMISSION)
- path_radiance_accum_emission(L, throughput, volume_segment.accum_emission, state->bounce);
-
- /* scattering */
- VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED;
-
- if(volume_segment.closure_flag & SD_SCATTER) {
- int all = false;
-
- /* direct light sampling */
- kernel_branched_path_volume_connect_light(kg, &sd,
- emission_sd, throughput, state, L, all,
- &volume_ray, &volume_segment);
-
- /* indirect 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, state, PRNG_PHASE);
- float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
-
- result = kernel_volume_decoupled_scatter(kg,
- state, &volume_ray, &sd, &throughput,
- rphase, rscatter, &volume_segment, NULL, true);
- }
-
- /* free cached steps */
- kernel_volume_decoupled_free(kg, &volume_segment);
-
- if(result == VOLUME_PATH_SCATTERED) {
- if(kernel_path_volume_bounce(kg, &sd, &throughput, state, L, ray))
- continue;
- else
- break;
- }
- else {
- throughput *= volume_segment.accum_transmittance;
- }
- }
- else
-# endif /* __VOLUME_DECOUPLED__ */
- {
- /* integrate along volume segment with distance sampling */
- VolumeIntegrateResult result = kernel_volume_integrate(
- kg, state, &sd, &volume_ray, L, &throughput, heterogeneous);
-
-# ifdef __VOLUME_SCATTER__
- if(result == VOLUME_PATH_SCATTERED) {
- /* direct lighting */
- kernel_path_volume_connect_light(kg, &sd, emission_sd, throughput, state, L);
-
- /* indirect light bounce */
- if(kernel_path_volume_bounce(kg, &sd, &throughput, state, L, ray))
- continue;
- else
- break;
- }
-# endif /* __VOLUME_SCATTER__ */
- }
+ bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
+
+ /* Find intersection with lamps and compute emission for MIS. */
+ kernel_path_lamp_emission(kg, state, ray, throughput, &isect, emission_sd, L);
+
+ /* Volume integration. */
+ VolumeIntegrateResult result = kernel_path_volume(kg,
+ &sd,
+ state,
+ ray,
+ &throughput,
+ &isect,
+ hit,
+ emission_sd,
+ L);
+
+ if(result == VOLUME_PATH_SCATTERED) {
+ continue;
+ }
+ else if(result == VOLUME_PATH_MISSED) {
+ break;
}
-#endif /* __VOLUME__ */
+ /* Shade background. */
if(!hit) {
- /* eval background shader if nothing hit */
- if(kernel_data.background.transparent && (state->flag & PATH_RAY_CAMERA)) {
- L->transparent += average(throughput);
-
-#ifdef __PASSES__
- if(!(kernel_data.film.pass_flag & PASS_BACKGROUND))
-#endif /* __PASSES__ */
- break;
- }
-
-#ifdef __BACKGROUND__
- /* sample background shader */
- float3 L_background = indirect_background(kg, emission_sd, state, ray);
- path_radiance_accum_background(L, state, throughput, L_background);
-#endif /* __BACKGROUND__ */
-
+ kernel_path_background(kg, state, ray, throughput, emission_sd, L);
break;
}
else if(path_state_ao_bounce(kg, state)) {
break;
}
- /* setup shading */
+ /* Setup and evaluate shader. */
shader_setup_from_ray(kg, &sd, &isect, ray);
float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
shader_eval_surface(kg, &sd, state, rbsdf, state->flag);
-#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_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 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__ */
-
- /* holdout */
-#ifdef __HOLDOUT__
- if(((sd.flag & SD_HOLDOUT) ||
- (sd.object_flag & SD_OBJECT_HOLDOUT_MASK)) &&
- (state->flag & PATH_RAY_CAMERA))
+ /* Apply shadow catcher, holdout, emission. */
+ if(!kernel_path_shader_apply(kg,
+ &sd,
+ state,
+ ray,
+ throughput,
+ emission_sd,
+ L,
+ buffer))
{
- if(kernel_data.background.transparent) {
- float3 holdout_weight;
- if(sd.object_flag & SD_OBJECT_HOLDOUT_MASK) {
- holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
- }
- else {
- holdout_weight = shader_holdout_eval(kg, &sd);
- }
- /* any throughput is ok, should all be identical here */
- L->transparent += average(holdout_weight*throughput);
- }
-
- if(sd.object_flag & SD_OBJECT_HOLDOUT_MASK) {
- break;
- }
- }
-#endif /* __HOLDOUT__ */
-
- /* holdout mask objects do not write data passes */
- kernel_write_data_passes(kg, buffer, L, &sd, state->sample, state, throughput);
-
- /* 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) {
- float blur_pdf = kernel_data.integrator.filter_glossy*state->min_ray_pdf;
-
- if(blur_pdf < 1.0f) {
- float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f;
- shader_bsdf_blur(kg, &sd, blur_roughness);
- }
- }
-
-#ifdef __EMISSION__
- /* emission */
- if(sd.flag & SD_EMISSION) {
- /* todo: is isect.t wrong here for transparent surfaces? */
- float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state->flag, state->ray_pdf);
- path_radiance_accum_emission(L, throughput, emission, state->bounce);
+ break;
}
-#endif /* __EMISSION__ */
/* 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
@@ -798,7 +713,6 @@ ccl_device void kernel_path_trace(KernelGlobals *kg,
path_radiance_init(&L, kernel_data.film.use_light_pass);
ShaderData emission_sd;
-
PathState state;
path_state_init(kg, &emission_sd, &state, rng_hash, sample, &ray);
diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h
index d4cfe461ac4..daab7c86f7f 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -48,9 +48,7 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg,
light_ray.P = ray_offset(sd->P, sd->Ng);
light_ray.D = ao_D;
light_ray.t = kernel_data.background.ao_distance;
-#ifdef __OBJECT_MOTION__
light_ray.time = sd->time;
-#endif /* __OBJECT_MOTION__ */
light_ray.dP = sd->dP;
light_ray.dD = differential3_zero();
@@ -292,36 +290,9 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
* Indirect bounces are handled in kernel_branched_path_surface_indirect_light().
*/
for(;;) {
- /* intersect scene */
+ /* Find intersection with objects in scene. */
Intersection isect;
- uint visibility = path_state_ray_visibility(kg, &state);
-
-#ifdef __HAIR__
- float difl = 0.0f, extmax = 0.0f;
- uint lcg_state = 0;
-
- if(kernel_data.bvh.have_curves) {
- if(kernel_data.cam.resolution == 1) {
- 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);
- }
-
- bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax);
-#else
- bool hit = scene_intersect(kg, ray, visibility, &isect, NULL, 0.0f, 0.0f);
-#endif /* __HAIR__ */
-
-#ifdef __KERNEL_DEBUG__
- 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__ */
+ bool hit = kernel_path_scene_intersect(kg, &state, &ray, &isect, L);
#ifdef __VOLUME__
/* Sanitize volume stack. */
@@ -464,79 +435,29 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
}
#endif /* __VOLUME__ */
+ /* Shade background. */
if(!hit) {
- /* eval background shader if nothing hit */
- if(kernel_data.background.transparent) {
- L->transparent += average(throughput);
-
-#ifdef __PASSES__
- if(!(kernel_data.film.pass_flag & PASS_BACKGROUND))
-#endif /* __PASSES__ */
- break;
- }
-
-#ifdef __BACKGROUND__
- /* sample background shader */
- float3 L_background = indirect_background(kg, &emission_sd, &state, &ray);
- path_radiance_accum_background(L, &state, throughput, L_background);
-#endif /* __BACKGROUND__ */
-
+ kernel_path_background(kg, &state, &ray, throughput, &emission_sd, L);
break;
}
- /* setup shading */
+ /* Setup and evaluate shader. */
shader_setup_from_ray(kg, &sd, &isect, &ray);
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)) {
- 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 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__ */
-
- /* holdout */
-#ifdef __HOLDOUT__
- if((sd.flag & SD_HOLDOUT) || (sd.object_flag & SD_OBJECT_HOLDOUT_MASK)) {
- if(kernel_data.background.transparent) {
- float3 holdout_weight;
- if(sd.object_flag & SD_OBJECT_HOLDOUT_MASK) {
- holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
- }
- else {
- holdout_weight = shader_holdout_eval(kg, &sd);
- }
- /* any throughput is ok, should all be identical here */
- L->transparent += average(holdout_weight*throughput);
- }
- if(sd.object_flag & SD_OBJECT_HOLDOUT_MASK) {
- break;
- }
- }
-#endif /* __HOLDOUT__ */
-
- /* holdout mask objects do not write data passes */
- kernel_write_data_passes(kg, buffer, L, &sd, sample, &state, throughput);
-
-#ifdef __EMISSION__
- /* emission */
- if(sd.flag & SD_EMISSION) {
- float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, state.ray_pdf);
- path_radiance_accum_emission(L, throughput, emission, state.bounce);
+ /* Apply shadow catcher, holdout, emission. */
+ if(!kernel_path_shader_apply(kg,
+ &sd,
+ &state,
+ &ray,
+ throughput,
+ &emission_sd,
+ L,
+ buffer))
+ {
+ break;
}
-#endif /* __EMISSION__ */
/* transparency termination */
if(state.flag & PATH_RAY_TRANSPARENT) {
diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h
index 3fd34ed10e2..e7e24f853c2 100644
--- a/intern/cycles/kernel/kernel_path_volume.h
+++ b/intern/cycles/kernel/kernel_path_volume.h
@@ -40,9 +40,7 @@ ccl_device_inline void kernel_path_volume_connect_light(
bool is_lamp;
/* connect to light from given point where shader has been evaluated */
-# ifdef __OBJECT_MOTION__
light_ray.time = sd->time;
-# endif
if(light_sample(kg, light_u, light_v, sd->time, sd->P, state->bounce, &ls))
{
@@ -134,9 +132,7 @@ ccl_device void kernel_branched_path_volume_connect_light(
BsdfEval L_light;
bool is_lamp;
-# ifdef __OBJECT_MOTION__
light_ray.time = sd->time;
-# endif
if(sample_all_lights) {
/* lamp sampling */
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index dd64f5b05ba..5964aca0c78 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -66,8 +66,8 @@ ccl_device_noinline void shader_setup_from_ray(KernelGlobals *kg,
/* matrices and time */
#ifdef __OBJECT_MOTION__
shader_setup_object_transforms(kg, sd, ray->time);
- sd->time = ray->time;
#endif
+ sd->time = ray->time;
sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
sd->ray_length = isect->t;
@@ -271,17 +271,17 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg,
sd->u = u;
sd->v = v;
#endif
+ sd->time = time;
sd->ray_length = t;
sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*SHADER_SIZE);
sd->object_flag = 0;
if(sd->object != OBJECT_NONE) {
sd->object_flag |= kernel_tex_fetch(__object_flag,
- sd->object);
+ sd->object);
#ifdef __OBJECT_MOTION__
shader_setup_object_transforms(kg, sd, time);
- sd->time = time;
}
else if(lamp != LAMP_NONE) {
sd->ob_tfm = lamp_fetch_transform(kg, lamp, false);
@@ -385,9 +385,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
sd->shader = kernel_data.background.surface_shader;
sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*SHADER_SIZE);
sd->object_flag = 0;
-#ifdef __OBJECT_MOTION__
sd->time = ray->time;
-#endif
sd->ray_length = 0.0f;
#ifdef __INSTANCING__
@@ -427,9 +425,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *s
sd->shader = SHADER_NONE;
sd->flag = 0;
sd->object_flag = 0;
-#ifdef __OBJECT_MOTION__
sd->time = ray->time;
-#endif
sd->ray_length = 0.0f; /* todo: can we set this to some useful value? */
#ifdef __INSTANCING__
diff --git a/intern/cycles/kernel/split/kernel_direct_lighting.h b/intern/cycles/kernel/split/kernel_direct_lighting.h
index 5009828df92..2aac66ecb84 100644
--- a/intern/cycles/kernel/split/kernel_direct_lighting.h
+++ b/intern/cycles/kernel/split/kernel_direct_lighting.h
@@ -94,9 +94,7 @@ ccl_device void kernel_direct_lighting(KernelGlobals *kg,
&ls)) {
Ray light_ray;
-# ifdef __OBJECT_MOTION__
light_ray.time = sd->time;
-# endif
BsdfEval L_light;
bool is_lamp;
diff --git a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
index 253b78526e7..733c25f5aa4 100644
--- a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
+++ b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
@@ -94,125 +94,42 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
ccl_global PathState *state = 0x0;
float3 throughput;
- uint sample;
ccl_global char *ray_state = kernel_split_state.ray_state;
ShaderData *sd = &kernel_split_state.sd[ray_index];
- ccl_global float *buffer = kernel_split_params.buffer;
if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
uint work_index = kernel_split_state.work_array[ray_index];
- sample = get_work_sample(kg, work_index, ray_index) + kernel_split_params.start_sample;
-
uint pixel_x, pixel_y, tile_x, tile_y;
get_work_pixel_tile_position(kg, &pixel_x, &pixel_y,
&tile_x, &tile_y,
work_index,
ray_index);
+ ccl_global float *buffer = kernel_split_params.buffer;
buffer += (kernel_split_params.offset + pixel_x + pixel_y * stride) * kernel_data.film.pass_stride;
+ ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
+ ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+
throughput = kernel_split_state.throughput[ray_index];
state = &kernel_split_state.path_state[ray_index];
-#ifdef __SHADOW_TRICKS__
- if((sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) {
- if(state->flag & PATH_RAY_CAMERA) {
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- state->flag |= (PATH_RAY_SHADOW_CATCHER |
- PATH_RAY_STORE_SHADOW_INFO);
- if(!kernel_data.background.transparent) {
- ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
- L->shadow_background_color = indirect_background(
- kg,
- &kernel_split_state.sd_DL_shadow[ray_index],
- state,
- ray);
- }
- L->shadow_radiance_sum = path_radiance_clamp_and_sum(kg, L);
- L->shadow_throughput = average(throughput);
- }
- }
- else if(state->flag & PATH_RAY_SHADOW_CATCHER) {
- /* Only update transparency after shadow catcher bounce. */
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- L->shadow_transparency *= average(shader_bsdf_transparency(kg, sd));
- }
-#endif /* __SHADOW_TRICKS__ */
-
- /* holdout */
-#ifdef __HOLDOUT__
- if(((sd->flag & SD_HOLDOUT) ||
- (sd->object_flag & SD_OBJECT_HOLDOUT_MASK)) &&
- (state->flag & PATH_RAY_CAMERA))
+ if(!kernel_path_shader_apply(kg,
+ sd,
+ state,
+ ray,
+ throughput,
+ emission_sd,
+ L,
+ buffer))
{
- if(kernel_data.background.transparent) {
- float3 holdout_weight;
- if(sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
- holdout_weight = make_float3(1.0f, 1.0f, 1.0f);
- }
- else {
- holdout_weight = shader_holdout_eval(kg, sd);
- }
- /* any throughput is ok, should all be identical here */
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- L->transparent += average(holdout_weight*throughput);
- }
- if(sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
- kernel_split_path_end(kg, ray_index);
- }
+ kernel_split_path_end(kg, ray_index);
}
-#endif /* __HOLDOUT__ */
}
if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
-
-#ifdef __BRANCHED_PATH__
- if(!IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT))
-#endif /* __BRANCHED_PATH__ */
- {
- /* Holdout mask objects do not write data passes. */
- kernel_write_data_passes(kg,
- buffer,
- L,
- sd,
- sample,
- state,
- throughput);
- }
-
- /* Blurring of bsdf after bounces, for rays that have a small likelihood
- * of following this particular path (diffuse, rough glossy.
- */
-#ifndef __BRANCHED_PATH__
- if(kernel_data.integrator.filter_glossy != FLT_MAX)
-#else
- if(kernel_data.integrator.filter_glossy != FLT_MAX &&
- (!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)))
-#endif /* __BRANCHED_PATH__ */
- {
- float blur_pdf = kernel_data.integrator.filter_glossy*state->min_ray_pdf;
- if(blur_pdf < 1.0f) {
- float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f;
- shader_bsdf_blur(kg, sd, blur_roughness);
- }
- }
-
-#ifdef __EMISSION__
- /* emission */
- if(sd->flag & SD_EMISSION) {
- /* TODO(sergey): is isect.t wrong here for transparent surfaces? */
- float3 emission = indirect_primitive_emission(
- kg,
- sd,
- kernel_split_state.isect[ray_index].t,
- state->flag,
- state->ray_pdf);
- path_radiance_accum_emission(L, throughput, emission, state->bounce);
- }
-#endif /* __EMISSION__ */
-
/* 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.
@@ -249,6 +166,7 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
}
}
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
kernel_update_denoising_features(kg, sd, state, L);
}
}
diff --git a/intern/cycles/kernel/split/kernel_indirect_background.h b/intern/cycles/kernel/split/kernel_indirect_background.h
index 2e9231caa3e..437043a5971 100644
--- a/intern/cycles/kernel/split/kernel_indirect_background.h
+++ b/intern/cycles/kernel/split/kernel_indirect_background.h
@@ -50,32 +50,16 @@ ccl_device void kernel_indirect_background(KernelGlobals *kg)
return;
}
- ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
- PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
- ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
-
if(IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND)) {
- /* eval background shader if nothing hit */
- if(kernel_data.background.transparent && (state->flag & PATH_RAY_CAMERA)) {
- L->transparent += average((*throughput));
-#ifdef __PASSES__
- if(!(kernel_data.film.pass_flag & PASS_BACKGROUND))
-#endif
- kernel_split_path_end(kg, ray_index);
- }
+ ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
+ float3 throughput = kernel_split_state.throughput[ray_index];
+ ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
- if(IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND)) {
-#ifdef __BACKGROUND__
- /* sample background shader */
- float3 L_background = indirect_background(kg, &kernel_split_state.sd_DL_shadow[ray_index], state, ray);
- path_radiance_accum_background(L, state, (*throughput), L_background);
-#endif
- kernel_split_path_end(kg, ray_index);
- }
+ kernel_path_background(kg, state, ray, throughput, emission_sd, L);
+ kernel_split_path_end(kg, ray_index);
}
-
-
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/split/kernel_lamp_emission.h b/intern/cycles/kernel/split/kernel_lamp_emission.h
index c669d79ddcd..448456d167d 100644
--- a/intern/cycles/kernel/split/kernel_lamp_emission.h
+++ b/intern/cycles/kernel/split/kernel_lamp_emission.h
@@ -57,27 +57,10 @@ ccl_device void kernel_lamp_emission(KernelGlobals *kg)
float3 throughput = kernel_split_state.throughput[ray_index];
Ray ray = kernel_split_state.ray[ray_index];
+ ccl_global Intersection *isect = &kernel_split_state.isect[ray_index];
+ ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
-#ifdef __LAMP_MIS__
- if(kernel_data.integrator.use_lamp_mis && !(state->flag & PATH_RAY_CAMERA)) {
- /* ray starting from previous non-transparent bounce */
- Ray light_ray;
-
- light_ray.P = ray.P - state->ray_t*ray.D;
- state->ray_t += kernel_split_state.isect[ray_index].t;
- light_ray.D = ray.D;
- light_ray.t = state->ray_t;
- light_ray.time = ray.time;
- light_ray.dD = ray.dD;
- light_ray.dP = ray.dP;
- /* intersect with lamp */
- float3 emission;
-
- if(indirect_lamp_emission(kg, &kernel_split_state.sd_DL_shadow[ray_index], state, &light_ray, &emission)) {
- path_radiance_accum_emission(L, throughput, emission, state->bounce);
- }
- }
-#endif /* __LAMP_MIS__ */
+ kernel_path_lamp_emission(kg, state, &ray, throughput, isect, emission_sd, L);
}
}
diff --git a/intern/cycles/kernel/split/kernel_scene_intersect.h b/intern/cycles/kernel/split/kernel_scene_intersect.h
index 99095f8fcbc..f5378bc172b 100644
--- a/intern/cycles/kernel/split/kernel_scene_intersect.h
+++ b/intern/cycles/kernel/split/kernel_scene_intersect.h
@@ -59,53 +59,13 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg)
return;
}
- Intersection isect;
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);
-
- if(path_state_ao_bounce(kg, state)) {
- visibility = PATH_RAY_SHADOW;
- ray.t = kernel_data.background.ao_distance;
- }
-
-#ifdef __HAIR__
- float difl = 0.0f, extmax = 0.0f;
- uint lcg_state = 0;
-
- if(kernel_data.bvh.have_curves) {
- 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_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;
-
-#ifdef __KERNEL_DEBUG__
PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
- 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;
- }
- L->debug_data.num_ray_bounces++;
-#endif
+ Intersection isect;
+ bool hit = kernel_path_scene_intersect(kg, state, &ray, &isect, L);
+ kernel_split_state.isect[ray_index] = isect;
if(!hit) {
/* Change the state of rays that hit the background;