31 #define DISABLE_SPHERICAL_PERTURBATIONS 0 33 #define SPHERICAL_SCREEN_PERTURBATIONS 0 34 #define DISK_SCREEN_SPACE_PERTURBATION 1 37 #include <mlt_perturbations.h> 39 #include <cugar/basic/timer.h> 40 #include <cugar/basic/cuda/timer.h> 41 #include <cugar/basic/primitives.h> 43 #include <cugar/color/rgbe.h> 47 #include <bpt_utils.h> 48 #include <bpt_context.h> 49 #include <bpt_control.h> 50 #include <bpt_samplers.h> 51 #include <tiled_sampling.h> 52 #include <path_inversion.h> 58 bool valid_sample(
const float3 f)
61 cugar::is_finite(f.x) && cugar::is_finite(f.y) && cugar::is_finite(f.z) &&
62 !cugar::is_nan(f.x) && !cugar::is_nan(f.y) && !cugar::is_nan(f.z);
66 bool valid_non_zero_sample(
const float3 f)
69 cugar::max_comp( f ) > 0.0f &&
73 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
81 template <
typename PathVertexType>
82 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
85 const cugar::Vector3f old_in = reconstruct_input_edge( v_prev, v, renderer );
89 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
92 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
101 uint32 n_light_paths;
103 float4* connections_value;
104 uint4* connections_index;
105 uint32* connections_counter;
122 uint32 enable_mutations;
123 float* acceptance_rate_sum;
126 float4* mut_f_vertices;
140 _mlt.m_light_vertices.view(),
141 _mlt.m_queues.view(_mlt.m_n_init_paths, _mlt.m_n_init_paths),
143 sequence(_mlt.m_sequence.view()),
144 mesh_light( options.use_vpls ? _renderer.mesh_vpls : _renderer.mesh_light )
147 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
148 float u_m(
const uint32 chain_id,
const uint32 dim)
const {
return cugar::randfloat( dim, chain_id + n_chains * chain_step ); }
150 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
151 void discard(
const uint32 chain_id)
153 Q_old[chain_id] = 1.0f;
154 Q_new[chain_id] = 0.0f;
157 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
158 bool discard_invalid(
const uint32 chain_id)
160 if (!valid_sample( Q_old[chain_id].xyz() ) ||
161 !valid_sample( Q_new[chain_id].xyz() ))
176 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
177 MLTPresamplingBPTConfig(
MLTContext& _context) :
180 VertexSampling::kAll,
181 VertexOrdering::kRandomOrdering,
182 VertexSampling::kAll,
187 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
188 void visit_light_vertex(
189 const uint32 light_path_id,
195 if (context.bpt_light_vertices)
196 context.bpt_light_vertices[light_path_id + depth * context.n_light_paths] = v_id;
201 FERMAT_HOST_DEVICE FERMAT_FORCEINLINE
202 void visit_eye_vertex(
203 const uint32 eye_path_id,
210 if (context.bpt_eye_vertices)
211 context.bpt_eye_vertices[eye_path_id + depth * context.n_eye_paths] = v_id;
225 const uint32 channel,
227 const uint32 light_path_id,
228 const uint32 eye_path_id,
234 if (cugar::max_comp(value.xyz()) > 0.0f)
237 context.connections_value[slot] = value;
238 context.connections_index[slot] = make_uint4(light_path_id, eye_path_id, s, t);
240 cugar::atomic_add(context.st_norms + s + t * (context.options.max_path_length + 2), cugar::max_comp(value.xyz()));
245 struct DecorrelatedRandoms
248 DecorrelatedRandoms(
const uint32 _dim,
const uint32 _seed) : dim(_dim), seed(_seed) {}
260 FERMAT_DEVICE FERMAT_FORCEINLINE
264 const float new_pdf = cugar::max_comp(w.xyz());
265 const float old_pdf = context.path_pdf[chain_id];
267 FERMAT_ASSERT( cugar::is_finite(old_pdf) && !cugar::is_nan(old_pdf) );
268 FERMAT_ASSERT( cugar::is_finite(new_pdf) && !cugar::is_nan(new_pdf) );
269 FERMAT_ASSERT( old_pdf >= 0.0f );
270 FERMAT_ASSERT( new_pdf >= 0.0f );
272 const Path old_path(s + t, context.vertices + chain_id, context.n_chains);
273 const Path new_path(s + t, context.mut_vertices + chain_id, context.n_chains);
280 const uint32 old_pixel = old_pixel_x + old_pixel_y*renderer.res_x;
284 const uint32 new_pixel = new_pixel_x + new_pixel_y*renderer.res_x;
290 const float Q_old = cugar::max_comp( context.Q_old[chain_id].xyz() );
291 const float Q_new = cugar::max_comp( context.Q_new[chain_id].xyz() );
292 const float ar = Q_old ? cugar::min( 1.0f, Q_new / Q_old ) : (Q_new ? 1.0f : 0.0f);
293 FERMAT_ASSERT( cugar::is_finite(Q_old) && !cugar::is_nan(Q_old) );
294 FERMAT_ASSERT( cugar::is_finite(Q_new) && !cugar::is_nan(Q_new) );
295 FERMAT_ASSERT( cugar::is_finite(ar) && !cugar::is_nan(ar) );
296 FERMAT_ASSERT( ar >= 0.0f );
300 const float4 old_value = context.path_value[chain_id];
302 atomicAdd(&renderer.fb(FBufferDesc::COMPOSITED_C, old_pixel).x, context.pdf_norm * (1.0f - ar) * (old_value.x / old_pdf) / float(renderer.instance + 1));
303 atomicAdd(&renderer.fb(FBufferDesc::COMPOSITED_C, old_pixel).y, context.pdf_norm * (1.0f - ar) * (old_value.y / old_pdf) / float(renderer.instance + 1));
304 atomicAdd(&renderer.fb(FBufferDesc::COMPOSITED_C, old_pixel).z, context.pdf_norm * (1.0f - ar) * (old_value.z / old_pdf) / float(renderer.instance + 1));
308 const float4 new_value = w;
310 atomicAdd(&renderer.fb(FBufferDesc::COMPOSITED_C, new_pixel).x, context.pdf_norm * ar * (new_value.x / new_pdf) /
float(renderer.instance + 1));
311 atomicAdd(&renderer.fb(FBufferDesc::COMPOSITED_C, new_pixel).y, context.pdf_norm * ar * (new_value.y / new_pdf) /
float(renderer.instance + 1));
312 atomicAdd(&renderer.fb(FBufferDesc::COMPOSITED_C, new_pixel).z, context.pdf_norm * ar * (new_value.z / new_pdf) /
float(renderer.instance + 1));
315 if (context.u_m(chain_id, (context.options.max_path_length + 1) * 3) < ar)
317 context.path_value[chain_id] = w;
318 context.path_pdf[chain_id] = new_pdf;
321 for (uint32 i = 0; i < s + t; ++i)
323 context.vertices[chain_id + i * context.n_chains] = context.mut_vertices[chain_id + i * context.n_chains];
324 context.f_vertices[chain_id + i * context.n_chains] = context.mut_f_vertices[chain_id + i * context.n_chains];
327 context.rejections[chain_id] = 0;
331 context.rejections[chain_id]++;
350 const uint32 s_old = context.st[chain_id].x;
351 const uint32 t_old = context.st[chain_id].y;
354 const uint32 t = (context.enable_mutations ==
false) || (context.options.st_perturbations ==
false) || (s_old == 0) ?
357 const uint32 s = s_old + t_old - t;
358 FERMAT_ASSERT(s + t == s_old + t_old);
361 context.st[chain_id] = make_char4(s_old, t_old, s, t);
370 context.light_vertices.vertex_path_id[chain_id] = uint32(-1);
371 context.light_vertices.vertex_weights[chain_id] =
PathWeights(1.0f, 0.0f);
383 photon = context.vertices[chain_id];
386 context.mesh_light.
map(photon.prim_id, photon.uv, &geom, &pdf, &edf);
389 Path path(s + t, context.mut_vertices + chain_id, context.n_chains);
390 path.v_L(0) = photon;
393 PathCache<float4> f_path(s + t, context.mut_f_vertices + chain_id, context.n_chains);
398 context.Q_old[chain_id] *= 1.0f / pdf;
399 context.Q_new[chain_id] *= 1.0f / pdf;
404 context.light_vertices.vertex[chain_id] =
VPL(photon.prim_id, photon.uv, 1.0f);
405 context.light_vertices.vertex_path_id[chain_id] = chain_id;
406 context.light_vertices.vertex_gbuffer[chain_id] = make_uint4(cugar::to_rgbe(edf.color), 0, 0, __float_as_uint(pdf));
407 context.light_vertices.vertex_pos[chain_id] =
cugar::Vector4f(geom.position, __uint_as_float(packed_normal));
408 context.light_vertices.vertex_input[chain_id] = make_uint2(0, cugar::to_rgbe(
cugar::Vector3f(1.0f)));
409 context.light_vertices.vertex_weights[chain_id] =
PathWeights(
417 context.light_vertices.vertex_path_id[chain_id] = uint32(-1);
423 const Path old_path(s + t, context.vertices + chain_id, context.n_chains);
424 const PathCache<float4> old_f_path(s + t, context.f_vertices + chain_id, context.n_chains);
436 for (uint32 i = 0; i < 2; ++i)
437 samples[i] = context.u_m(chain_id, 3 + i);
440 const cugar::Vector3f out = context.enable_mutations ? spherical_perturbation(geom, out_old, samples, context.options.perturbation_radius) : out_old;
448 if (cugar::max_comp(f))
450 FERMAT_ASSERT( cugar::max_comp(f) > 0.0f );
452 out_ray.origin = geom.position;
454 out_ray.tmin = 1.0e-4f;
455 out_ray.tmax = 1.0e8f;
457 context.Q_old[chain_id] *= old_f_path.v_L(0) * cos_theta(
interpolate_normal(renderer.mesh, old_v), out_old );
458 context.Q_new[chain_id] *= f_path.v_L(0) * cos_theta( geom.normal_s, out );
459 FERMAT_ASSERT(valid_sample(context.Q_old[chain_id].xyz()));
464 const float p_proj = edf.
p(geom, geom.position, out, cugar::kProjectedSolidAngle);
465 const TempPathWeights out_path_weights = TempPathWeights::light_vertex_1( pdf, p_proj, fabsf(dot(geom.normal_s, out)) );
467 scatter_queue.warp_append(
468 PixelInfo(chain_id, FBufferDesc::DIFFUSE_C),
477 context.discard( chain_id );
486 const PixelInfo pixel_info = in_queue.pixels[task_id];
487 const Ray ray = in_queue.rays[task_id];
488 const Hit hit = in_queue.hits[task_id];
491 const uint32 in_bounce = context.in_bounce;
493 const uint32 chain_id = pixel_info.pixel;
495 *out_chain_id = chain_id;
497 const uint32 s = context.st[chain_id].z;
498 const uint32 t = context.st[chain_id].w;
500 if (hit.t > 0.0f && hit.triId >= 0)
503 Path path(s + t, context.mut_vertices + chain_id, context.n_chains);
507 PathCache<float4> f_path(s + t, context.mut_f_vertices + chain_id, context.n_chains);
511 lv.setup(ray, hit, w.xyz(), path_weights, in_bounce + 1, renderer);
514 if (in_bounce + 2 == s)
516 const uint32 slot = chain_id;
521 context.light_vertices.vertex[slot] =
VPL(hit.triId,
cugar::Vector2f(hit.u, hit.v), w.w);
522 context.light_vertices.vertex_path_id[slot] = pixel_info.pixel;
523 context.light_vertices.vertex_gbuffer[slot] = make_uint4(
526 cugar::binary_cast<uint32>(lv.material.roughness),
528 context.light_vertices.vertex_pos[slot] =
cugar::Vector4f(lv.geom.position, __uint_as_float(packed_normal));
529 context.light_vertices.vertex_input[slot] = make_uint2(packed_direction, cugar::to_rgbe(w.xyz()));
530 context.light_vertices.vertex_weights[slot] =
PathWeights(
536 if (in_bounce + 2 < s)
540 for (uint32 i = 0; i < 3; ++i)
541 samples[i] = context.u_m(chain_id, (in_bounce + 2) * 3 + i);
544 const Path old_path(s + t, context.vertices + chain_id, context.n_chains);
545 const PathCache<float4> old_f_path(s + t, context.f_vertices + chain_id, context.n_chains);
557 const float u_p = context.enable_mutations ?
558 context.u_m(chain_id, (in_bounce + 2) * 3 + 2) :
561 if (u_p < context.options.exp_perturbations)
564 out = spherical_perturbation(lv.geom, out_old, samples.xy(), context.options.perturbation_radius);
566 else if (u_p < context.options.H_perturbations
567 + context.options.exp_perturbations)
570 const LightVertex old_lv = reconstruct_vertex<LightVertex>( old_path.v_L(in_bounce), old_v, in_bounce, renderer );
573 out = H_perturbation(old_lv, out_old, lv, samples.xy(), context.options.perturbation_radius);
582 if (u_p < context.options.exp_perturbations)
584 context.Q_old[chain_id] *= old_f_path.v_L(in_bounce + 1) * cos_theta(
interpolate_normal(renderer.mesh, old_v), out_old );
585 context.Q_new[chain_id] *= f_path.v_L(in_bounce + 1) * cos_theta( lv.geom.normal_s, out );
586 FERMAT_ASSERT(valid_sample(context.Q_old[chain_id].xyz()));
588 else if (u_p < context.options.H_perturbations
589 + context.options.exp_perturbations)
592 const LightVertex old_lv = reconstruct_vertex<LightVertex>( old_path.v_L(in_bounce), old_v, in_bounce, renderer );
594 context.Q_old[chain_id] *= old_f_path.v_L(in_bounce + 1) * H_perturbation_geometric_density( old_lv, out_old ) * cos_theta( old_lv.geom.normal_s, out_old );
595 context.Q_new[chain_id] *= f_path.v_L(in_bounce + 1) * H_perturbation_geometric_density( lv, out ) * cos_theta( lv.geom.normal_s, out );
596 FERMAT_ASSERT(valid_sample(context.Q_old[chain_id].xyz()));
600 context.Q_old[chain_id] *= old_f_path.v_L(in_bounce + 1) * cos_theta(
interpolate_normal(renderer.mesh, old_v), out_old );
601 context.Q_new[chain_id] *= f_path.v_L(in_bounce + 1) * cos_theta( lv.geom.normal_s, out );
602 FERMAT_ASSERT(valid_sample(context.Q_old[chain_id].xyz()));
608 if (valid_non_zero_sample( out_w.xyz() ))
612 out_ray.origin = lv.geom.position;
614 out_ray.tmin = 1.0e-4f;
615 out_ray.tmax = 1.0e8f;
619 const float p_proj = lv.bsdf.
p(lv.geom, lv.in, out, cugar::kProjectedSolidAngle);
622 scatter_queue.warp_append(
632 context.discard( chain_id );
642 context.discard( chain_id );
646 return (in_bounce + 2 == s);
652 const uint32 s = context.st[chain_id].z;
653 const uint32 t = context.st[chain_id].w;
656 Path old_path(s + t, context.vertices + chain_id, context.n_chains);
673 const float u_p = context.u_m(chain_id, (s + t - 2)*3 + 2);
675 if (context.enable_mutations && u_p < context.options.screen_perturbations)
679 for (uint32 i = 0; i < 2; ++i)
680 samples[i] = context.u_m(chain_id, (s + t - 2)*3 + i);
682 #if SPHERICAL_SCREEN_PERTURBATIONS 687 uv = renderer.camera_sampler.
invert(out);
688 #elif DISK_SCREEN_SPACE_PERTURBATION 694 const float phi = samples.x*2.0f*M_PIf;
695 const float r = dist.
map(samples.y);
706 Path path(s + t, context.mut_vertices + chain_id, context.n_chains);
712 ((float4*)out_queue.rays)[2 * out_slot + 0] = make_float4(ray_origin.x, ray_origin.y, ray_origin.z, 0.0f);
713 ((float4*)out_queue.rays)[2 * out_slot + 1] = make_float4(ray_direction.x, ray_direction.y, ray_direction.z, 1e34f);
716 out_queue.pixels[out_slot] = chain_id;
723 const float W_e = renderer.camera_sampler.
W_e(new_out);
726 PathCache<float4> f_path(s + t, context.mut_f_vertices + chain_id, context.n_chains);
730 PathCache<float4> old_f_path(s + t, context.f_vertices + chain_id, context.n_chains);
732 #if SPHERICAL_SCREEN_PERTURBATIONS 733 const float old_cos_theta_o = (dot( old_out, renderer.camera_sampler.W ) / renderer.camera_sampler.W_len);
734 const float new_cos_theta_o = (dot( new_out, renderer.camera_sampler.W ) / renderer.camera_sampler.W_len);
736 context.Q_old[chain_id] *= old_f_path.v_E(0) * old_cos_theta_o;
737 context.Q_new[chain_id] *= f_path.v_E(0) * new_cos_theta_o;
740 const float new_pdf = renderer.camera_sampler.
pdf(new_out,
true);
741 const float old_pdf = renderer.camera_sampler.
pdf(old_out,
true);
743 context.Q_old[chain_id] *= old_pdf ? old_f_path.v_E(0) / old_pdf :
cugar::Vector4f(1.0f);
744 context.Q_new[chain_id] *= new_pdf ? f_path.v_E(0) / new_pdf :
cugar::Vector4f(0.0f);
751 const float p_e = W_e;
752 const float cos_theta = (dot( new_out, renderer.camera_sampler.W ) / renderer.camera_sampler.W_len);
753 out_queue.path_weights[out_slot] = TempPathWeights::eye_vertex_1( p_e, cos_theta, context.options.light_tracing );
759 const PixelInfo pixel_info = in_queue.pixels[task_id];
760 const Ray ray = in_queue.rays[task_id];
761 const Hit hit = in_queue.hits[task_id];
764 const uint32 in_bounce = context.in_bounce;
766 const uint32 chain_id = pixel_info.pixel;
768 const uint32 s = context.st[chain_id].z;
769 const uint32 t = context.st[chain_id].w;
771 bool invalidate_sample =
false;
772 bool accumulated_path =
false;
775 if (hit.t > 0.0f && hit.triId >= 0)
778 Path path(s + t, context.mut_vertices + chain_id, context.n_chains);
782 PathCache<float4> f_path(s + t, context.mut_f_vertices + chain_id, context.n_chains);
785 const Path old_path(s + t, context.vertices + chain_id, context.n_chains);
786 PathCache<float4> old_f_path(s + t, context.f_vertices + chain_id, context.n_chains);
790 ev.setup(ray, hit, w.xyz(), path_weights, in_bounce, renderer);
793 if (in_bounce + 2 == t && s > 0)
796 const uint32 light_idx = chain_id;
798 const uint32 light_depth = s - 1;
801 cugar::Vector4f light_pos = context.light_vertices.vertex_pos[light_idx];
802 const uint2 light_in = context.light_vertices.vertex_input[light_idx];
803 uint4 light_gbuffer = context.light_vertices.vertex_gbuffer[light_idx];
804 PathWeights light_weights = context.light_vertices.vertex_weights[light_idx];
805 const uint32 light_path_id = context.light_vertices.vertex_path_id[light_idx];
807 if (light_path_id != uint32(-1))
810 LightVertex lv(light_pos, light_in, light_gbuffer, light_weights, light_depth, renderer);
826 if (!context.options.mis)
829 out_f = out_f_L * out_f_s;
836 const float old_G = old_path.G(s-1, renderer);
839 context.Q_old[chain_id] *= old_f_path.v_E(t-1) * old_f_path.v_L(s-1) * old_G;
840 context.Q_new[chain_id] *= f_path.v_E(t-1) * f_path.v_L(s-1) * out_G;
841 context.discard_invalid( chain_id );
845 if (valid_non_zero_sample( out_w.xyz() ))
849 out_ray.origin = ev.geom.position + ev.in * SHADOW_BIAS;
850 out_ray.dir = (lv.geom.position - out_ray.origin);
851 out_ray.tmin = SHADOW_TMIN;
852 out_ray.tmax = 0.9999f;
856 PixelInfo(pixel_info.pixel, FBufferDesc::DIRECT_C);
858 context.shadow_queue.warp_append(
864 accumulated_path =
true;
869 invalidate_sample =
true;
875 invalidate_sample =
true;
880 if (in_bounce + 2 == t && s == 0)
888 context.mesh_light.
map(ev.geom_id.prim_id, ev.geom_id.uv, &light_vertex_geom, &light_pdf, &light_edf);
890 const cugar::Vector3f f_L = light_edf.
f(light_vertex_geom, light_vertex_geom.position, ev.in);
896 context.Q_old[chain_id] *= old_f_path.v_L(0);
897 context.Q_new[chain_id] *= f_path.v_L(0);
898 context.discard_invalid( chain_id );
901 if (context.options.mis)
904 const float p_L = light_edf.
p(light_vertex_geom, light_vertex_geom.position, ev.in, cugar::kProjectedSolidAngle);
905 const float pGp = p_L * light_pdf;
906 const float prev_pGp = ev.prev_pG * p_L;
907 mis_w = mis_selector(
909 (ev.depth == 0 || pGp == 0.0f) ? 1.0f :
910 bpt_mis(pGp, prev_pGp, ev.pGp_sum));
915 if (valid_non_zero_sample( out_w.xyz() ))
916 accumulated_value = out_w;
920 invalidate_sample =
true;
923 accumulated_path =
false;
927 if (in_bounce + 2 < t)
931 for (uint32 i = 0; i < 3; ++i)
932 samples[i] = context.u_m(chain_id, (s + t - in_bounce - 2) * 3 + i);
944 const float u_p = context.enable_mutations ?
945 context.u_m(chain_id, (s + t - in_bounce - 2) * 3 + 2) :
948 if (u_p < context.options.exp_perturbations)
951 out = spherical_perturbation(ev.geom, out_old, samples.xy(), context.options.perturbation_radius);
953 else if (u_p < context.options.H_perturbations
954 + context.options.exp_perturbations)
957 const EyeVertex old_ev = reconstruct_vertex<EyeVertex>( old_path.v_E(in_bounce), old_v, in_bounce, renderer );
960 out = H_perturbation(old_ev, out_old, ev, samples.xy(), context.options.perturbation_radius);
970 if (u_p < context.options.exp_perturbations)
972 context.Q_old[chain_id] *= old_f_path.v_E(in_bounce + 1) * cos_theta(
interpolate_normal(renderer.mesh, old_v), out_old );
973 context.Q_new[chain_id] *= f_path.v_E(in_bounce + 1) * cos_theta( ev.geom.normal_s, out );
974 context.discard_invalid(chain_id);
976 else if (u_p < context.options.H_perturbations
977 + context.options.exp_perturbations)
980 const EyeVertex old_ev = reconstruct_vertex<EyeVertex>( old_path.v_E(in_bounce), old_v, in_bounce, renderer );
982 context.Q_old[chain_id] *= old_f_path.v_E(in_bounce + 1) * H_perturbation_geometric_density( old_ev, out_old ) * cos_theta( old_ev.geom.normal_s, out_old );
983 context.Q_new[chain_id] *= f_path.v_E(in_bounce + 1) * H_perturbation_geometric_density( ev, out ) * cos_theta( ev.geom.normal_s, out );
984 context.discard_invalid(chain_id);
988 context.Q_old[chain_id] *= old_f_path.v_E(in_bounce + 1) * cos_theta(
interpolate_normal(renderer.mesh, old_v), out_old );
989 context.Q_new[chain_id] *= f_path.v_E(in_bounce + 1) * cos_theta( ev.geom.normal_s, out );
990 context.discard_invalid( chain_id );
996 if (valid_non_zero_sample( out_w.xyz() ))
998 const uint32 channel = FBufferDesc::COMPOSITED_C;
1002 out_ray.origin = ev.geom.position;
1004 out_ray.tmin = 1.0e-4f;
1005 out_ray.tmax = 1.0e8f;
1011 const float p_proj = ev.bsdf.
p(ev.geom, ev.in, out, cugar::kProjectedSolidAngle);
1014 scatter_queue.warp_append(
1020 accumulated_path =
true;
1025 invalidate_sample =
true;
1035 invalidate_sample =
true;
1038 if (invalidate_sample)
1041 context.discard( chain_id );
1044 if (accumulated_path ==
false)
1047 accept_reject_accumulate(chain_id, s, t, accumulated_value, context, renderer);
1054 const PixelInfo pixel_info = context.shadow_queue.pixels[task_id];
1055 const Hit hit = context.shadow_queue.hits[task_id];
1058 const uint32 chain_id = pixel_info.pixel;
1059 const uint32 s = context.st[chain_id].z;
1060 const uint32 t = context.st[chain_id].w;
1062 const float vis = (hit.t < 0.0f) ? 1.0f : 0.0f;
1065 context.Q_new[chain_id] *= vis;
1068 accept_reject_accumulate(chain_id, s, t, w * vis, context, renderer);
FERMAT_HOST_DEVICE FERMAT_FORCEINLINE float pdf(const cugar::Vector3f out, const bool projected=false) const
Definition: camera.h:286
CUGAR_HOST_DEVICE float map(const float U) const
Definition: distributions.h:255
CUGAR_HOST_DEVICE uint32 quantize(const float x, const uint32 n)
Definition: numbers.h:600
FERMAT_HOST_DEVICE FERMAT_FORCEINLINE float W_e(const cugar::Vector3f out) const
Definition: camera.h:294
Defines various distributions.
float CUGAR_HOST_DEVICE mod(const float x, const float m)
Definition: numbers.h:606
Definition: bpt_utils.h:110
Definition: distributions.h:234
Definition: ray_queues.h:57
FERMAT_HOST_DEVICE void map(const uint32_t prim_id, const cugar::Vector2f &uv, VertexGeometry *geom, float *pdf, Edf *edf) const
Definition: lights.h:584
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float atomic_add(float *value, const float op)
Definition: atomics.h:100
Definition: bpt_utils.h:131
FERMAT_HOST_DEVICE FERMAT_FORCEINLINE cugar::Vector3f sample_direction(const cugar::Vector2f ndc) const
Definition: camera.h:278
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE T dot(const Vector< T, DIM > &op1, const Vector< T, DIM > &op2)
Definition: tensor_inl.h:309
Definition: tiled_sequence.h:53
FERMAT_HOST_DEVICE FERMAT_FORCEINLINE uint32 pack_direction(const cugar::Vector3f &dir)
Definition: vertex.h:123
Definition: bpt_utils.h:583
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Vector3f f(const DifferentialGeometry &geometry, const Vector3f in, const Vector3f out) const
Definition: lambert_edf.h:60
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float p(const DifferentialGeometry &geometry, const Vector3f in, const Vector3f out, const SphericalMeasure measure=kProjectedSolidAngle) const
Definition: lambert_edf.h:80
Definition: bpt_context.h:54
Definition: bpt_kernels.h:216
FERMAT_HOST_DEVICE void eval_connection_terms(const EyeVertex ev, const LightVertex &lv, cugar::Vector3f &out, cugar::Vector3f &f_conn, float &G, float &d)
Definition: bpt_utils.h:768
Definition: bpt_kernels.h:56
Definition: mlt_core.h:98
Definition: pathtracer_core.h:527
FERMAT_HOST_DEVICE cugar::Vector3f interpolate_position(const MeshView &mesh, const uint32 tri_id, const float u, const float v, float *pdf=0)
Definition: mesh_utils.h:323
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE cugar::Vector3f f(const cugar::DifferentialGeometry &geometry, const cugar::Vector3f w_i, const cugar::Vector3f w_o, const ComponentType components=kAllComponents) const
Definition: bsdf.h:312
Definition: renderer_view.h:80
FERMAT_HOST_DEVICE FERMAT_FORCEINLINE cugar::Vector2f invert(const cugar::Vector3f out) const
Definition: camera.h:305
Definition: bpt_utils.h:311
FERMAT_HOST_DEVICE cugar::Vector3f interpolate_normal(const MeshView &mesh, const uint32 tri_id, const float u, const float v)
Definition: mesh_utils.h:350
Define CUDA based warp adders.
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float randfloat(unsigned i, unsigned p)
Definition: numbers.h:753
FERMAT_FORCEINLINE FERMAT_HOST_DEVICE float p(const cugar::DifferentialGeometry &geometry, const cugar::Vector3f w_i, const cugar::Vector3f w_o, const cugar::SphericalMeasure measure=cugar::kProjectedSolidAngle, const bool RR=true, const ComponentType components=kAllComponents) const
Definition: bsdf.h:474