[Bf-blender-cvs] [51a1d64] master: Cycles code refactor: deduplicate and symmetrize some path tracing code.
Brecht Van Lommel
noreply at git.blender.org
Sat Jun 14 13:55:29 CEST 2014
Commit: 51a1d6481b3fe27bcc41a635835c006e9010f94d
Author: Brecht Van Lommel
Date: Fri Apr 4 14:21:35 2014 +0200
https://developer.blender.org/rB51a1d6481b3fe27bcc41a635835c006e9010f94d
Cycles code refactor: deduplicate and symmetrize some path tracing code.
===================================================================
M intern/cycles/kernel/kernel_bake.h
M intern/cycles/kernel/kernel_path.h
===================================================================
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index e8845e0..a2ff6a0 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -69,7 +69,9 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
path_radiance_accum_emission(&L_sample, throughput, emission, state.bounce);
}
- if(kernel_path_integrate_lighting(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) {
+ kernel_path_surface_connect_light(kg, &rng, sd, throughput, &state, &L_sample);
+
+ if(kernel_path_surface_bounce(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) {
#ifdef __LAMP_MIS__
state.ray_t = 0.0f;
#endif
@@ -107,7 +109,17 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
path_radiance_accum_emission(&L_sample, throughput, emission, state.bounce);
}
- kernel_branched_path_integrate_lighting(kg, &rng,
+#if defined(__EMISSION__)
+ /* direct light */
+ if(kernel_data.integrator.use_direct_light) {
+ bool all = kernel_data.integrator.sample_all_lights_direct;
+ kernel_branched_path_surface_connect_light(kg, &rng,
+ sd, &state, throughput, 1.0f, &L_sample, all);
+ }
+#endif
+
+ /* indirect light */
+ kernel_branched_path_surface_indirect_light(kg, &rng,
sd, throughput, 1.0f, &state, &L_sample);
}
}
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 70366ea..f5606c0 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -47,40 +47,45 @@ CCL_NAMESPACE_BEGIN
#ifdef __VOLUME__
-ccl_device_inline bool kernel_path_integrate_scatter_lighting(KernelGlobals *kg, RNG *rng,
- ShaderData *sd, float3 *throughput, PathState *state, PathRadiance *L, Ray *ray,
- float num_samples_adjust)
+ccl_device_inline void kernel_path_volume_connect_light(KernelGlobals *kg, RNG *rng,
+ ShaderData *sd, float3 throughput, PathState *state, PathRadiance *L, float num_samples_adjust)
{
#ifdef __EMISSION__
- if(kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL)) {
- /* sample illumination from lights to find path contribution */
- float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
- float light_u, light_v;
- path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
+ if(!(kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL)))
+ return;
- Ray light_ray;
- BsdfEval L_light;
- bool is_lamp;
+ /* sample illumination from lights to find path contribution */
+ float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
+ float light_u, light_v;
+ path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
+
+ Ray light_ray;
+ BsdfEval L_light;
+ bool is_lamp;
#ifdef __OBJECT_MOTION__
- light_ray.time = sd->time;
+ light_ray.time = sd->time;
#endif
- LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ LightSample ls;
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
- if(direct_emission(kg, sd, &ls, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
- /* trace shadow ray */
- float3 shadow;
+ if(direct_emission(kg, sd, &ls, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
+ /* trace shadow ray */
+ float3 shadow;
- if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
- /* accumulate */
- path_radiance_accum_light(L, *throughput * num_samples_adjust, &L_light, shadow, 1.0f, state->bounce, is_lamp);
- }
+ if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, throughput * num_samples_adjust, &L_light, shadow, 1.0f, state->bounce, is_lamp);
}
}
#endif
+}
+ccl_device_inline bool kernel_path_volume_bounce(KernelGlobals *kg, RNG *rng,
+ ShaderData *sd, float3 *throughput, PathState *state, PathRadiance *L, Ray *ray,
+ float num_samples_adjust)
+{
/* sample phase function */
float phase_pdf;
BsdfEval phase_eval;
@@ -126,7 +131,8 @@ ccl_device_inline bool kernel_path_integrate_scatter_lighting(KernelGlobals *kg,
#if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__)
-ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg, RNG *rng,
+/* branched path tracing: connect path directly to position on one or more lights and add it to L */
+ccl_device void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RNG *rng,
ShaderData *sd, PathState *state, float3 throughput, float num_samples_adjust, PathRadiance *L, bool sample_all_lights)
{
/* sample illumination from lights to find path contribution */
@@ -224,6 +230,122 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg
#endif
+/* path tracing: connect path directly to position on a light and add it to L */
+ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG *rng,
+ ShaderData *sd, float3 throughput, PathState *state, PathRadiance *L)
+{
+#ifdef __EMISSION__
+ if(!(kernel_data.integrator.use_direct_light) && (sd->flag & SD_BSDF_HAS_EVAL))
+ return;
+
+ float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
+ float light_u, light_v;
+ path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
+
+ Ray light_ray;
+ BsdfEval L_light;
+ bool is_lamp;
+
+#ifdef __OBJECT_MOTION__
+ light_ray.time = sd->time;
+#endif
+
+ LightSample ls;
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+
+ if(direct_emission(kg, sd, &ls, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
+ /* trace shadow ray */
+ float3 shadow;
+
+ if(!shadow_blocked(kg, state, &light_ray, &shadow)) {
+ /* accumulate */
+ path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp);
+ }
+ }
+#endif
+}
+
+/* path tracing: bounce off or through surface to with new direction stored in ray */
+ccl_device_inline bool kernel_path_surface_bounce(KernelGlobals *kg, RNG *rng,
+ ShaderData *sd, float3 *throughput, PathState *state, PathRadiance *L, Ray *ray)
+{
+ /* no BSDF? we can stop here */
+ if(sd->flag & SD_BSDF) {
+ /* sample BSDF */
+ float bsdf_pdf;
+ BsdfEval bsdf_eval;
+ float3 bsdf_omega_in;
+ differential3 bsdf_domega_in;
+ float bsdf_u, bsdf_v;
+ path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
+ int label;
+
+ label = shader_bsdf_sample(kg, sd, bsdf_u, bsdf_v, &bsdf_eval,
+ &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
+
+ if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
+ return false;
+
+ /* modify throughput */
+ path_radiance_bsdf_bounce(L, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
+
+ /* set labels */
+ if(!(label & LABEL_TRANSPARENT)) {
+ state->ray_pdf = bsdf_pdf;
+#ifdef __LAMP_MIS__
+ state->ray_t = 0.0f;
+#endif
+ state->min_ray_pdf = fminf(bsdf_pdf, state->min_ray_pdf);
+ }
+
+ /* update path state */
+ path_state_next(kg, state, label);
+
+ /* setup ray */
+ ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT)? -sd->Ng: sd->Ng);
+ ray->D = bsdf_omega_in;
+
+ if(state->bounce == 0)
+ ray->t -= sd->ray_length; /* clipping works through transparent */
+ else
+ ray->t = FLT_MAX;
+
+#ifdef __RAY_DIFFERENTIALS__
+ ray->dP = sd->dP;
+ ray->dD = bsdf_domega_in;
+#endif
+
+#ifdef __VOLUME__
+ /* enter/exit volume */
+ if(label & LABEL_TRANSMIT)
+ kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
+#endif
+ return true;
+ }
+#ifdef __VOLUME__
+ else if(sd->flag & SD_HAS_ONLY_VOLUME) {
+ /* no surface shader but have a volume shader? act transparent */
+
+ /* update path state, count as transparent */
+ path_state_next(kg, state, LABEL_TRANSPARENT);
+
+ /* setup ray position, direction stays unchanged */
+ ray->P = ray_offset(sd->P, -sd->Ng);
+#ifdef __RAY_DIFFERENTIALS__
+ ray->dP = sd->dP;
+#endif
+
+ /* enter/exit volume */
+ kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
+ return true;
+ }
+#endif
+ else {
+ /* no bsdf or volume? */
+ return false;
+ }
+}
+
ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray,
float3 throughput, int num_samples, PathState state, PathRadiance *L)
{
@@ -270,7 +392,9 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray,
&volume_sd, &volume_ray, L, &throughput, rng);
if(result == VOLUME_PATH_SCATTERED) {
- if(kernel_path_integrate_scatter_lighting(kg, rng, &volume_sd, &throughput, &state, L, &ray, 1.0f))
+ kernel_path_volume_connect_light(kg, rng, &volume_sd, throughput, &state, L, 1.0f);
+
+ if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, &state, L, &ray, 1.0f))
continue;
else
break;
@@ -393,190 +517,12 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray,
#if defined(__EMISSION__) && defined(__BRANCHED_PATH__)
if(kernel_data.integrator.use_direct_light) {
bool all = kernel_data.integrator.sample_all_lights_indirect;
- kernel_branched_path_integrate_direct_lighting(kg, rng, &sd, &state, throughput, 1.0f, L, all);
- }
-#endif
-
- /* no BSDF? we can stop here */
- if(sd.flag & SD_BSDF) {
- /* sample BSDF */
- float bsdf_pdf;
- BsdfEval bsdf_eval;
- float3 bsdf_omega_in;
- differential3 bsdf_domega_in;
- float bsdf_u, bsdf_v;
- path_state_rng_2D(kg, rng, &state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
- int label;
-
- label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval,
- &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
-
- if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
- break;
-
- /* modify throughput */
- path_radiance_bsdf_bounce(L, &throughput, &bsdf_eval, bsdf_pdf, state.bounce, label);
-
- /* set labels */
- if(!(label & LABEL_TRANSPARENT)) {
- state.ray_pdf = bsdf_pdf;
-#ifdef __LAMP_MIS__
- state.ray_t = 0.0f;
-#endif
- state.min_ray_pdf = fminf(bsdf_pdf, state.min_ray_pdf);
- }
-
- /* update path state */
- path_state_next(kg, &state, label);
-
- /* setup ray */
- ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng);
- ray.D = bsdf_omega_in;
- ray.t = FLT_MAX;
-#ifdef __RAY_DIF
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list