diff options
Diffstat (limited to 'intern/cycles/kernel/kernel_path.h')
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 581 |
1 files changed, 9 insertions, 572 deletions
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 9b9495644dd..9794ad1d180 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -42,6 +42,7 @@ #include "kernel_path_state.h" #include "kernel_shadow.h" #include "kernel_emission.h" +#include "kernel_path_common.h" #include "kernel_path_surface.h" #include "kernel_path_volume.h" @@ -273,8 +274,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, float bssrdf_u, bssrdf_v; path_state_rng_2D(kg, rng, &state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false); - - state.flag |= PATH_RAY_BSSRDF_ANCESTOR; } } #endif @@ -307,17 +306,17 @@ ccl_device void kernel_path_ao(KernelGlobals *kg, ShaderData *sd, PathRadiance * sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); - if(dot(sd->Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { + if(dot(ccl_fetch(sd, Ng), ao_D) > 0.0f && ao_pdf != 0.0f) { Ray light_ray; float3 ao_shadow; - light_ray.P = ray_offset(sd->P, sd->Ng); + light_ray.P = ray_offset(ccl_fetch(sd, P), ccl_fetch(sd, Ng)); light_ray.D = ao_D; light_ray.t = kernel_data.background.ao_distance; #ifdef __OBJECT_MOTION__ - light_ray.time = sd->time; + light_ray.time = ccl_fetch(sd, time); #endif - light_ray.dP = sd->dP; + light_ray.dP = ccl_fetch(sd, dP); light_ray.dD = differential3_zero(); if(!shadow_blocked(kg, state, &light_ray, &ao_shadow)) @@ -325,70 +324,8 @@ ccl_device void kernel_path_ao(KernelGlobals *kg, ShaderData *sd, PathRadiance * } } -ccl_device void kernel_branched_path_ao(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, PathState *state, RNG *rng, float3 throughput) -{ - int num_samples = kernel_data.integrator.ao_samples; - float num_samples_inv = 1.0f/num_samples; - float ao_factor = kernel_data.background.ao_factor; - float3 ao_N; - float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N); - float3 ao_alpha = shader_bsdf_alpha(kg, sd); - - 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); - - float3 ao_D; - float ao_pdf; - - sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); - - if(dot(sd->Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { - Ray light_ray; - float3 ao_shadow; - - 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 - light_ray.dP = sd->dP; - light_ray.dD = differential3_zero(); - - if(!shadow_blocked(kg, state, &light_ray, &ao_shadow)) - path_radiance_accum_ao(L, throughput*num_samples_inv, ao_alpha, ao_bsdf, ao_shadow, state->bounce); - } - } -} - #ifdef __SUBSURFACE__ -#ifdef __VOLUME__ -ccl_device void kernel_path_subsurface_update_volume_stack(KernelGlobals *kg, - Ray *ray, - VolumeStack *stack) -{ - kernel_assert(kernel_data.integrator.use_volumes); - - Ray volume_ray = *ray; - Intersection isect; - int step = 0; - while(step < VOLUME_STACK_SIZE && - scene_intersect_volume(kg, &volume_ray, &isect)) - { - ShaderData sd; - shader_setup_from_ray(kg, &sd, &isect, &volume_ray, 0, 0); - kernel_volume_stack_enter_exit(kg, &sd, stack); - - /* Move ray forward. */ - volume_ray.P = ray_offset(sd.P, -sd.Ng); - volume_ray.t -= sd.ray_length; - ++step; - } -} -#endif - ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, PathState *state, RNG *rng, Ray *ray, float3 *throughput) { float bssrdf_probability; @@ -408,7 +345,7 @@ ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd #ifdef __VOLUME__ Ray volume_ray = *ray; bool need_update_volume_stack = kernel_data.integrator.use_volumes && - sd->flag & SD_OBJECT_INTERSECTS_VOLUME; + ccl_fetch(sd, flag) & SD_OBJECT_INTERSECTS_VOLUME; #endif /* compute lighting with the BSDF closure */ @@ -417,7 +354,6 @@ ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd PathState hit_state = *state; Ray hit_ray = *ray; - hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR; hit_state.rng_offset += PRNG_BOUNCE_NUM; kernel_path_surface_connect_light(kg, rng, &bssrdf_sd[hit], tp, state, L); @@ -433,7 +369,7 @@ ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd volume_ray.D = normalize_len(hit_ray.P - volume_ray.P, &volume_ray.t); - kernel_path_subsurface_update_volume_stack( + kernel_volume_stack_update_for_subsurface( kg, &volume_ray, hit_state.volume_stack); @@ -503,7 +439,9 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, #ifdef __KERNEL_DEBUG__ if(state.flag & PATH_RAY_CAMERA) { debug_data.num_bvh_traversal_steps += isect.num_traversal_steps; + debug_data.num_bvh_traversed_instances += isect.num_traversed_instances; } + debug_data.num_ray_bounces++; #endif #ifdef __LAMP_MIS__ @@ -733,474 +671,6 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent); } -#ifdef __BRANCHED_PATH__ - -/* branched path tracing: bounce off surface and integrate indirect light */ -ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGlobals *kg, - RNG *rng, ShaderData *sd, float3 throughput, float num_samples_adjust, - PathState *state, PathRadiance *L) -{ - for(int i = 0; i< sd->num_closure; i++) { - const ShaderClosure *sc = &sd->closure[i]; - - if(!CLOSURE_IS_BSDF(sc->type)) - continue; - /* transparency is not handled here, but in outer loop */ - if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) - continue; - - int num_samples; - - if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) - num_samples = kernel_data.integrator.diffuse_samples; - else if(CLOSURE_IS_BSDF_BSSRDF(sc->type)) - num_samples = 1; - else if(CLOSURE_IS_BSDF_GLOSSY(sc->type)) - num_samples = kernel_data.integrator.glossy_samples; - else - num_samples = kernel_data.integrator.transmission_samples; - - 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; - - if(!kernel_branched_path_surface_bounce(kg, &bsdf_rng, sd, sc, j, num_samples, &tp, &ps, L, &bsdf_ray)) - continue; - - kernel_path_indirect(kg, rng, bsdf_ray, tp*num_samples_inv, num_samples, ps, L); - - /* for render passes, sum and reset indirect light pass variables - * for the next samples */ - path_radiance_sum_indirect(L); - path_radiance_reset_indirect(L); - } - } -} - -#ifdef __SUBSURFACE__ -ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, - ShaderData *sd, - PathRadiance *L, - PathState *state, - RNG *rng, - Ray *ray, - float3 throughput) -{ - for(int i = 0; i< sd->num_closure; i++) { - ShaderClosure *sc = &sd->closure[i]; - - if(!CLOSURE_IS_BSSRDF(sc->type)) - continue; - - /* set up random number generator */ - uint lcg_state = lcg_state_init(rng, 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); - - state->flag |= PATH_RAY_BSSRDF_ANCESTOR; - - /* 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++) { - ShaderData bssrdf_sd[BSSRDF_MAX_HITS]; - float bssrdf_u, bssrdf_v; - path_branched_rng_2D(kg, &bssrdf_rng, state, j, num_samples, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); - int num_hits = subsurface_scatter_multi_step(kg, sd, bssrdf_sd, state->flag, sc, &lcg_state, bssrdf_u, bssrdf_v, true); -#ifdef __VOLUME__ - Ray volume_ray = *ray; - bool need_update_volume_stack = kernel_data.integrator.use_volumes && - sd->flag & SD_OBJECT_INTERSECTS_VOLUME; -#endif - - /* compute lighting with the BSDF closure */ - for(int hit = 0; hit < num_hits; hit++) { - PathState hit_state = *state; - - path_state_branch(&hit_state, j, num_samples); - -#ifdef __VOLUME__ - if(need_update_volume_stack) { - /* Setup ray from previous surface point to the new one. */ - float3 P = ray_offset(bssrdf_sd[hit].P, -bssrdf_sd[hit].Ng); - volume_ray.D = normalize_len(P - volume_ray.P, - &volume_ray.t); - - kernel_path_subsurface_update_volume_stack( - kg, - &volume_ray, - hit_state.volume_stack); - - /* Move volume ray forward. */ - volume_ray.P = P; - } -#endif - -#if defined(__EMISSION__) && defined(__BRANCHED_PATH__) - /* 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, - &bssrdf_sd[hit], &hit_state, throughput, num_samples_inv, L, all); - } -#endif - - /* indirect light */ - kernel_branched_path_surface_indirect_light(kg, rng, - &bssrdf_sd[hit], throughput, num_samples_inv, - &hit_state, L); - } - } - - state->flag &= ~PATH_RAY_BSSRDF_ANCESTOR; - } -} -#endif - -ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, ccl_global float *buffer) -{ - /* initialize */ - PathRadiance L; - 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); - - PathState state; - path_state_init(kg, &state, rng, sample, &ray); - -#ifdef __KERNEL_DEBUG__ - DebugData debug_data; - debug_data_init(&debug_data); -#endif - - for(;;) { - /* intersect 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(rng, &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 - -#ifdef __KERNEL_DEBUG__ - if(state.flag & PATH_RAY_CAMERA) { - debug_data.num_bvh_traversal_steps += isect.num_traversal_steps; - } -#endif - -#ifdef __VOLUME__ - /* 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__ - /* decoupled ray marching only supported on CPU */ - - /* cache steps along volume for repeated sampling */ - VolumeSegment volume_segment; - ShaderData volume_sd; - - shader_setup_from_volume(kg, &volume_sd, &volume_ray, state.bounce, state.transparent_bounce); - kernel_volume_decoupled_record(kg, &state, - &volume_ray, &volume_sd, &volume_segment, heterogeneous); - - /* direct light sampling */ - if(volume_segment.closure_flag & SD_SCATTER) { - volume_segment.sampling_method = volume_stack_sampling_method(kg, state.volume_stack); - - bool all = kernel_data.integrator.sample_all_lights_direct; - - kernel_branched_path_volume_connect_light(kg, rng, &volume_sd, - throughput, &state, &L, all, &volume_ray, &volume_segment); - - /* indirect light sampling */ - int num_samples = kernel_data.integrator.volume_samples; - float num_samples_inv = 1.0f/num_samples; - - for(int j = 0; j < num_samples; j++) { - /* workaround to fix correlation bug in T38710, can find better solution - * in random number generator later, for now this is done here to not impact - * performance of rendering without volumes */ - RNG tmp_rng = cmj_hash(*rng, state.rng_offset); - - PathState ps = state; - Ray pray = ray; - float3 tp = throughput; - - /* branch RNG state */ - path_state_branch(&ps, j, num_samples); - - /* 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, &tmp_rng, &ps, PRNG_PHASE); - float rscatter = path_state_rng_1D_for_decision(kg, &tmp_rng, &ps, PRNG_SCATTER_DISTANCE); - - VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, - &ps, &pray, &volume_sd, &tp, rphase, rscatter, &volume_segment, NULL, false); - - (void)result; - kernel_assert(result == VOLUME_PATH_SCATTERED); - - if(kernel_path_volume_bounce(kg, rng, &volume_sd, &tp, &ps, &L, &pray)) { - kernel_path_indirect(kg, rng, pray, tp*num_samples_inv, num_samples, ps, &L); - - /* for render passes, sum and reset indirect light pass variables - * for the next samples */ - path_radiance_sum_indirect(&L); - path_radiance_reset_indirect(&L); - } - } - } - - /* emission and transmittance */ - if(volume_segment.closure_flag & SD_EMISSION) - path_radiance_accum_emission(&L, throughput, volume_segment.accum_emission, state.bounce); - throughput *= volume_segment.accum_transmittance; - - /* free cached steps */ - kernel_volume_decoupled_free(kg, &volume_segment); -#else - /* GPU: no decoupled ray marching, scatter probalistically */ - int num_samples = kernel_data.integrator.volume_samples; - float num_samples_inv = 1.0f/num_samples; - - /* todo: we should cache the shader evaluations from stepping - * through the volume, for now we redo them multiple times */ - - for(int j = 0; j < num_samples; j++) { - PathState ps = state; - Ray pray = ray; - ShaderData volume_sd; - float3 tp = throughput * num_samples_inv; - - /* branch RNG state */ - path_state_branch(&ps, j, num_samples); - - VolumeIntegrateResult result = kernel_volume_integrate( - kg, &ps, &volume_sd, &volume_ray, &L, &tp, rng, 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, &volume_sd, tp, &state, &L); - - if(kernel_path_volume_bounce(kg, rng, &volume_sd, &tp, &ps, &L, &pray)) { - kernel_path_indirect(kg, rng, pray, tp, num_samples, ps, &L); - - /* for render passes, sum and reset indirect light pass variables - * for the next samples */ - path_radiance_sum_indirect(&L); - path_radiance_reset_indirect(&L); - } - } -#endif - } - - /* todo: avoid this calculation using decoupled ray marching */ - kernel_volume_shadow(kg, &state, &volume_ray, &throughput); -#endif - } -#endif - - 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 - break; - } - -#ifdef __BACKGROUND__ - /* sample background shader */ - float3 L_background = indirect_background(kg, &state, &ray); - path_radiance_accum_background(&L, throughput, L_background, state.bounce); -#endif - - break; - } - - /* setup shading */ - ShaderData sd; - shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce, state.transparent_bounce); - shader_eval_surface(kg, &sd, 0.0f, state.flag, SHADER_CONTEXT_MAIN); - shader_merge_closures(&sd); - - /* holdout */ -#ifdef __HOLDOUT__ - if(sd.flag & (SD_HOLDOUT|SD_HOLDOUT_MASK)) { - if(kernel_data.background.transparent) { - float3 holdout_weight; - - if(sd.flag & SD_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.flag & SD_HOLDOUT_MASK) - break; - } -#endif - - /* 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); - } -#endif - - /* transparency termination */ - if(state.flag & PATH_RAY_TRANSPARENT) { - /* 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); - - if(probability == 0.0f) { - break; - } - else if(probability != 1.0f) { - float terminate = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_TERMINATE); - - if(terminate >= probability) - break; - - throughput /= probability; - } - } - -#ifdef __AO__ - /* ambient occlusion */ - if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { - kernel_branched_path_ao(kg, &sd, &L, &state, rng, throughput); - } -#endif - -#ifdef __SUBSURFACE__ - /* bssrdf scatter to a different location on the same object */ - if(sd.flag & SD_BSSRDF) { - kernel_branched_path_subsurface_scatter(kg, &sd, &L, &state, - rng, &ray, throughput); - } -#endif - - if(!(sd.flag & SD_HAS_ONLY_VOLUME)) { - PathState hit_state = state; - -#ifdef __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, &hit_state, throughput, 1.0f, &L, all); - } -#endif - - /* indirect light */ - kernel_branched_path_surface_indirect_light(kg, rng, - &sd, throughput, 1.0f, &hit_state, &L); - - /* continue in case of transparency */ - throughput *= shader_bsdf_transparency(kg, &sd); - - if(is_zero(throughput)) - break; - } - - path_state_next(kg, &state, LABEL_TRANSPARENT); - ray.P = ray_offset(sd.P, -sd.Ng); - ray.t -= sd.ray_length; /* clipping works through transparent */ - - -#ifdef __RAY_DIFFERENTIALS__ - ray.dP = sd.dP; - ray.dD.dx = -sd.dI.dx; - ray.dD.dy = -sd.dI.dy; -#endif - -#ifdef __VOLUME__ - /* enter/exit volume */ - kernel_volume_stack_enter_exit(kg, &sd, state.volume_stack); -#endif - } - - float3 L_sum = path_radiance_clamp_and_sum(kg, &L); - - kernel_write_light_passes(kg, buffer, &L, sample); - -#ifdef __KERNEL_DEBUG__ - kernel_write_debug_passes(kg, buffer, &state, &debug_data, sample); -#endif - - return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent); -} - -#endif - -ccl_device_inline void kernel_path_trace_setup(KernelGlobals *kg, ccl_global uint *rng_state, int sample, int x, int y, RNG *rng, Ray *ray) -{ - float filter_u; - float filter_v; - - int num_samples = kernel_data.integrator.aa_samples; - - path_rng_init(kg, rng_state, sample, num_samples, rng, x, y, &filter_u, &filter_v); - - /* sample camera ray */ - - float lens_u = 0.0f, lens_v = 0.0f; - - if(kernel_data.cam.aperturesize > 0.0f) - path_rng_2D(kg, rng, sample, num_samples, PRNG_LENS_U, &lens_u, &lens_v); - - float time = 0.0f; - -#ifdef __CAMERA_MOTION__ - if(kernel_data.cam.shuttertime != -1.0f) - time = path_rng_1D(kg, rng, sample, num_samples, PRNG_TIME); -#endif - - camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, time, ray); -} - ccl_device void kernel_path_trace(KernelGlobals *kg, ccl_global float *buffer, ccl_global uint *rng_state, int sample, int x, int y, int offset, int stride) @@ -1232,38 +702,5 @@ ccl_device void kernel_path_trace(KernelGlobals *kg, path_rng_end(kg, rng_state, rng); } -#ifdef __BRANCHED_PATH__ -ccl_device void kernel_branched_path_trace(KernelGlobals *kg, - ccl_global float *buffer, ccl_global uint *rng_state, - int sample, int x, int y, int offset, int stride) -{ - /* buffer offset */ - int index = offset + x + y*stride; - int pass_stride = kernel_data.film.pass_stride; - - rng_state += index; - buffer += index*pass_stride; - - /* initialize random numbers and ray */ - RNG rng; - Ray ray; - - kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng, &ray); - - /* integrate */ - float4 L; - - if(ray.t != 0.0f) - L = kernel_branched_path_integrate(kg, &rng, sample, ray, buffer); - else - L = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - - /* accumulate result in output buffer */ - kernel_write_pass_float4(buffer, sample, L); - - path_rng_end(kg, rng_state, rng); -} -#endif - CCL_NAMESPACE_END |