Code cleanup: move rng into path state.

Also pass by value and don't write back now that it is just a hash for seeding
and no longer an LCG state. Together this makes CUDA a tiny bit faster in my
tests, but mainly simplifies code.
This commit is contained in:
Brecht Van Lommel
2017-08-19 04:11:25 +02:00
parent 1cc4033df8
commit cfa8b762e2
28 changed files with 192 additions and 271 deletions

View File

@@ -21,7 +21,7 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline void compute_light_pass(KernelGlobals *kg, ccl_device_inline void compute_light_pass(KernelGlobals *kg,
ShaderData *sd, ShaderData *sd,
PathRadiance *L, PathRadiance *L,
RNG rng, uint rng_hash,
int pass_filter, int pass_filter,
int sample) int sample)
{ {
@@ -48,11 +48,11 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
path_radiance_init(&L_sample, kernel_data.film.use_light_pass); path_radiance_init(&L_sample, kernel_data.film.use_light_pass);
/* init path state */ /* init path state */
path_state_init(kg, &emission_sd, &state, &rng, sample, NULL); path_state_init(kg, &emission_sd, &state, rng_hash, sample, NULL);
/* evaluate surface shader */ /* evaluate surface shader */
float rbsdf = path_state_rng_1D(kg, &rng, &state, PRNG_BSDF); float rbsdf = path_state_rng_1D(kg, &state, PRNG_BSDF);
shader_eval_surface(kg, sd, &rng, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN); shader_eval_surface(kg, sd, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
/* TODO, disable more closures we don't need besides transparent */ /* TODO, disable more closures we don't need besides transparent */
shader_bsdf_disable_transparency(kg, sd); shader_bsdf_disable_transparency(kg, sd);
@@ -64,7 +64,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
/* sample ambient occlusion */ /* sample ambient occlusion */
if(pass_filter & BAKE_FILTER_AO) { if(pass_filter & BAKE_FILTER_AO) {
kernel_path_ao(kg, sd, &emission_sd, &L_sample, &state, &rng, throughput, shader_bsdf_alpha(kg, sd)); kernel_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput, shader_bsdf_alpha(kg, sd));
} }
/* sample emission */ /* sample emission */
@@ -86,7 +86,6 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
&emission_sd, &emission_sd,
&L_sample, &L_sample,
&state, &state,
&rng,
&ray, &ray,
&throughput, &throughput,
&ss_indirect)) &ss_indirect))
@@ -101,7 +100,6 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
kernel_path_indirect(kg, kernel_path_indirect(kg,
&indirect_sd, &indirect_sd,
&emission_sd, &emission_sd,
&rng,
&ray, &ray,
throughput, throughput,
state.num_samples, state.num_samples,
@@ -116,14 +114,14 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
/* sample light and BSDF */ /* sample light and BSDF */
if(!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) { if(!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) {
kernel_path_surface_connect_light(kg, &rng, sd, &emission_sd, throughput, &state, &L_sample); kernel_path_surface_connect_light(kg, sd, &emission_sd, throughput, &state, &L_sample);
if(kernel_path_surface_bounce(kg, &rng, sd, &throughput, &state, &L_sample, &ray)) { if(kernel_path_surface_bounce(kg, sd, &throughput, &state, &L_sample, &ray)) {
#ifdef __LAMP_MIS__ #ifdef __LAMP_MIS__
state.ray_t = 0.0f; state.ray_t = 0.0f;
#endif #endif
/* compute indirect light */ /* compute indirect light */
kernel_path_indirect(kg, &indirect_sd, &emission_sd, &rng, &ray, throughput, 1, &state, &L_sample); kernel_path_indirect(kg, &indirect_sd, &emission_sd, &ray, throughput, 1, &state, &L_sample);
/* sum and reset indirect light pass variables for the next samples */ /* sum and reset indirect light pass variables for the next samples */
path_radiance_sum_indirect(&L_sample); path_radiance_sum_indirect(&L_sample);
@@ -137,7 +135,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
/* sample ambient occlusion */ /* sample ambient occlusion */
if(pass_filter & BAKE_FILTER_AO) { if(pass_filter & BAKE_FILTER_AO) {
kernel_branched_path_ao(kg, sd, &emission_sd, &L_sample, &state, &rng, throughput); kernel_branched_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput);
} }
/* sample emission */ /* sample emission */
@@ -151,7 +149,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) { if((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
/* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */ /* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
kernel_branched_path_subsurface_scatter(kg, sd, &indirect_sd, kernel_branched_path_subsurface_scatter(kg, sd, &indirect_sd,
&emission_sd, &L_sample, &state, &rng, &ray, throughput); &emission_sd, &L_sample, &state, &ray, throughput);
} }
#endif #endif
@@ -161,13 +159,13 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
/* direct light */ /* direct light */
if(kernel_data.integrator.use_direct_light) { if(kernel_data.integrator.use_direct_light) {
int all = kernel_data.integrator.sample_all_lights_direct; int all = kernel_data.integrator.sample_all_lights_direct;
kernel_branched_path_surface_connect_light(kg, &rng, kernel_branched_path_surface_connect_light(kg,
sd, &emission_sd, &state, throughput, 1.0f, &L_sample, all); sd, &emission_sd, &state, throughput, 1.0f, &L_sample, all);
} }
#endif #endif
/* indirect light */ /* indirect light */
kernel_branched_path_surface_indirect_light(kg, &rng, kernel_branched_path_surface_indirect_light(kg,
sd, &indirect_sd, &emission_sd, throughput, 1.0f, &state, &L_sample); sd, &indirect_sd, &emission_sd, throughput, 1.0f, &state, &L_sample);
} }
} }
@@ -225,7 +223,6 @@ ccl_device_inline float3 kernel_bake_shader_bsdf(KernelGlobals *kg,
ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg, ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
ShaderData *sd, ShaderData *sd,
RNG *rng,
PathState *state, PathState *state,
float3 direct, float3 direct,
float3 indirect, float3 indirect,
@@ -245,12 +242,12 @@ ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
} }
else { else {
/* surface color of the pass only */ /* surface color of the pass only */
shader_eval_surface(kg, sd, rng, state, 0.0f, 0, SHADER_CONTEXT_MAIN); shader_eval_surface(kg, sd, state, 0.0f, 0, SHADER_CONTEXT_MAIN);
return kernel_bake_shader_bsdf(kg, sd, type); return kernel_bake_shader_bsdf(kg, sd, type);
} }
} }
else { else {
shader_eval_surface(kg, sd, rng, state, 0.0f, 0, SHADER_CONTEXT_MAIN); shader_eval_surface(kg, sd, state, 0.0f, 0, SHADER_CONTEXT_MAIN);
color = kernel_bake_shader_bsdf(kg, sd, type); color = kernel_bake_shader_bsdf(kg, sd, type);
} }
@@ -292,14 +289,14 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
int num_samples = kernel_data.integrator.aa_samples; int num_samples = kernel_data.integrator.aa_samples;
/* random number generator */ /* random number generator */
RNG rng = cmj_hash(offset + i, kernel_data.integrator.seed); uint rng_hash = cmj_hash(offset + i, kernel_data.integrator.seed);
float filter_x, filter_y; float filter_x, filter_y;
if(sample == 0) { if(sample == 0) {
filter_x = filter_y = 0.5f; filter_x = filter_y = 0.5f;
} }
else { else {
path_rng_2D(kg, &rng, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y); path_rng_2D(kg, rng_hash, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y);
} }
/* subpixel u/v offset */ /* subpixel u/v offset */
@@ -335,14 +332,14 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
/* light passes if we need more than color */ /* light passes if we need more than color */
if(pass_filter & ~BAKE_FILTER_COLOR) if(pass_filter & ~BAKE_FILTER_COLOR)
compute_light_pass(kg, &sd, &L, rng, pass_filter, sample); compute_light_pass(kg, &sd, &L, rng_hash, pass_filter, sample);
switch(type) { switch(type) {
/* data passes */ /* data passes */
case SHADER_EVAL_NORMAL: case SHADER_EVAL_NORMAL:
{ {
if((sd.flag & SD_HAS_BUMP)) { if((sd.flag & SD_HAS_BUMP)) {
shader_eval_surface(kg, &sd, &rng, &state, 0.f, 0, SHADER_CONTEXT_MAIN); shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_MAIN);
} }
/* compression: normal = (2 * color) - 1 */ /* compression: normal = (2 * color) - 1 */
@@ -356,7 +353,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
} }
case SHADER_EVAL_EMISSION: case SHADER_EVAL_EMISSION:
{ {
shader_eval_surface(kg, &sd, &rng, &state, 0.f, 0, SHADER_CONTEXT_EMISSION); shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_EMISSION);
out = shader_emissive_eval(kg, &sd); out = shader_emissive_eval(kg, &sd);
break; break;
} }
@@ -409,7 +406,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
{ {
out = kernel_bake_evaluate_direct_indirect(kg, out = kernel_bake_evaluate_direct_indirect(kg,
&sd, &sd,
&rng,
&state, &state,
L.direct_diffuse, L.direct_diffuse,
L.indirect_diffuse, L.indirect_diffuse,
@@ -421,7 +417,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
{ {
out = kernel_bake_evaluate_direct_indirect(kg, out = kernel_bake_evaluate_direct_indirect(kg,
&sd, &sd,
&rng,
&state, &state,
L.direct_glossy, L.direct_glossy,
L.indirect_glossy, L.indirect_glossy,
@@ -433,7 +428,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
{ {
out = kernel_bake_evaluate_direct_indirect(kg, out = kernel_bake_evaluate_direct_indirect(kg,
&sd, &sd,
&rng,
&state, &state,
L.direct_transmission, L.direct_transmission,
L.indirect_transmission, L.indirect_transmission,
@@ -446,7 +440,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
#ifdef __SUBSURFACE__ #ifdef __SUBSURFACE__
out = kernel_bake_evaluate_direct_indirect(kg, out = kernel_bake_evaluate_direct_indirect(kg,
&sd, &sd,
&rng,
&state, &state,
L.direct_subsurface, L.direct_subsurface,
L.indirect_subsurface, L.indirect_subsurface,

View File

@@ -72,7 +72,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
/* no path flag, we're evaluating this for all closures. that's weak but /* no path flag, we're evaluating this for all closures. that's weak but
* we'd have to do multiple evaluations otherwise */ * we'd have to do multiple evaluations otherwise */
path_state_modify_bounce(state, true); path_state_modify_bounce(state, true);
shader_eval_surface(kg, emission_sd, NULL, state, 0.0f, 0, SHADER_CONTEXT_EMISSION); shader_eval_surface(kg, emission_sd, state, 0.0f, 0, SHADER_CONTEXT_EMISSION);
path_state_modify_bounce(state, false); path_state_modify_bounce(state, false);
/* evaluate emissive closure */ /* evaluate emissive closure */

View File

@@ -55,14 +55,13 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg,
ShaderData *emission_sd, ShaderData *emission_sd,
PathRadiance *L, PathRadiance *L,
ccl_addr_space PathState *state, ccl_addr_space PathState *state,
RNG *rng,
float3 throughput, float3 throughput,
float3 ao_alpha) float3 ao_alpha)
{ {
/* todo: solve correlation */ /* todo: solve correlation */
float bsdf_u, bsdf_v; float bsdf_u, bsdf_v;
path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
float ao_factor = kernel_data.background.ao_factor; float ao_factor = kernel_data.background.ao_factor;
float3 ao_N; float3 ao_N;
@@ -101,7 +100,6 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg,
ccl_device void kernel_path_indirect(KernelGlobals *kg, ccl_device void kernel_path_indirect(KernelGlobals *kg,
ShaderData *sd, ShaderData *sd,
ShaderData *emission_sd, ShaderData *emission_sd,
RNG *rng,
Ray *ray, Ray *ray,
float3 throughput, float3 throughput,
int num_samples, int num_samples,
@@ -200,7 +198,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
/* direct light sampling */ /* direct light sampling */
kernel_branched_path_volume_connect_light(kg, kernel_branched_path_volume_connect_light(kg,
rng,
sd, sd,
emission_sd, emission_sd,
throughput, throughput,
@@ -213,8 +210,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
/* indirect sample. if we use distance sampling and take just /* indirect sample. if we use distance sampling and take just
* one sample for direct and indirect light, we could share * one sample for direct and indirect light, we could share
* this computation, but makes code a bit complex */ * this computation, but makes code a bit complex */
float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE); float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
float rscatter = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE); float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
result = kernel_volume_decoupled_scatter(kg, result = kernel_volume_decoupled_scatter(kg,
state, state,
@@ -233,7 +230,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
if(result == VOLUME_PATH_SCATTERED) { if(result == VOLUME_PATH_SCATTERED) {
if(kernel_path_volume_bounce(kg, if(kernel_path_volume_bounce(kg,
rng,
sd, sd,
&throughput, &throughput,
state, state,
@@ -255,13 +251,12 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
{ {
/* integrate along volume segment with distance sampling */ /* integrate along volume segment with distance sampling */
VolumeIntegrateResult result = kernel_volume_integrate( VolumeIntegrateResult result = kernel_volume_integrate(
kg, state, sd, &volume_ray, L, &throughput, rng, heterogeneous); kg, state, sd, &volume_ray, L, &throughput, heterogeneous);
# ifdef __VOLUME_SCATTER__ # ifdef __VOLUME_SCATTER__
if(result == VOLUME_PATH_SCATTERED) { if(result == VOLUME_PATH_SCATTERED) {
/* direct lighting */ /* direct lighting */
kernel_path_volume_connect_light(kg, kernel_path_volume_connect_light(kg,
rng,
sd, sd,
emission_sd, emission_sd,
throughput, throughput,
@@ -270,7 +265,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
/* indirect light bounce */ /* indirect light bounce */
if(kernel_path_volume_bounce(kg, if(kernel_path_volume_bounce(kg,
rng,
sd, sd,
&throughput, &throughput,
state, state,
@@ -309,8 +303,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
sd, sd,
&isect, &isect,
ray); ray);
float rbsdf = path_state_rng_1D_for_decision(kg, rng, state, PRNG_BSDF); float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
shader_eval_surface(kg, sd, rng, state, rbsdf, state->flag, SHADER_CONTEXT_INDIRECT); shader_eval_surface(kg, sd, state, rbsdf, state->flag, SHADER_CONTEXT_INDIRECT);
#ifdef __BRANCHED_PATH__ #ifdef __BRANCHED_PATH__
shader_merge_closures(sd); shader_merge_closures(sd);
#endif /* __BRANCHED_PATH__ */ #endif /* __BRANCHED_PATH__ */
@@ -360,7 +354,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
break; break;
} }
else if(probability != 1.0f) { else if(probability != 1.0f) {
float terminate = path_state_rng_1D_for_decision(kg, rng, state, PRNG_TERMINATE); float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE);
if(terminate >= probability) if(terminate >= probability)
break; break;
@@ -373,7 +367,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
#ifdef __AO__ #ifdef __AO__
/* ambient occlusion */ /* ambient occlusion */
if(kernel_data.integrator.use_ambient_occlusion || (sd->flag & SD_AO)) { if(kernel_data.integrator.use_ambient_occlusion || (sd->flag & SD_AO)) {
kernel_path_ao(kg, sd, emission_sd, L, state, rng, throughput, make_float3(0.0f, 0.0f, 0.0f)); kernel_path_ao(kg, sd, emission_sd, L, state, throughput, make_float3(0.0f, 0.0f, 0.0f));
} }
#endif /* __AO__ */ #endif /* __AO__ */
@@ -389,11 +383,10 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
/* do bssrdf scatter step if we picked a bssrdf closure */ /* do bssrdf scatter step if we picked a bssrdf closure */
if(sc) { if(sc) {
uint lcg_state = lcg_state_init(rng, state->rng_offset, state->sample, 0x68bc21eb); uint lcg_state = lcg_state_init(state, 0x68bc21eb);
float bssrdf_u, bssrdf_v; float bssrdf_u, bssrdf_v;
path_state_rng_2D(kg, path_state_rng_2D(kg,
rng,
state, state,
PRNG_BSDF_U, PRNG_BSDF_U,
&bssrdf_u, &bssrdf_v); &bssrdf_u, &bssrdf_v);
@@ -414,7 +407,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
int all = (kernel_data.integrator.sample_all_lights_indirect) || int all = (kernel_data.integrator.sample_all_lights_indirect) ||
(state->flag & PATH_RAY_SHADOW_CATCHER); (state->flag & PATH_RAY_SHADOW_CATCHER);
kernel_branched_path_surface_connect_light(kg, kernel_branched_path_surface_connect_light(kg,
rng,
sd, sd,
emission_sd, emission_sd,
state, state,
@@ -425,7 +417,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
} }
#endif /* defined(__EMISSION__) */ #endif /* defined(__EMISSION__) */
if(!kernel_path_surface_bounce(kg, rng, sd, &throughput, state, L, ray)) if(!kernel_path_surface_bounce(kg, sd, &throughput, state, L, ray))
break; break;
} }
} }
@@ -433,7 +425,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
#endif /* defined(__BRANCHED_PATH__) || defined(__BAKING__) */ #endif /* defined(__BRANCHED_PATH__) || defined(__BAKING__) */
ccl_device_inline void kernel_path_integrate(KernelGlobals *kg, ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
RNG *rng, uint rng_hash,
int sample, int sample,
Ray ray, Ray ray,
ccl_global float *buffer, ccl_global float *buffer,
@@ -451,7 +443,7 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
ShaderData emission_sd; ShaderData emission_sd;
PathState state; PathState state;
path_state_init(kg, &emission_sd, &state, rng, sample, &ray); path_state_init(kg, &emission_sd, &state, rng_hash, sample, &ray);
#ifdef __SUBSURFACE__ #ifdef __SUBSURFACE__
SubsurfaceIndirectRays ss_indirect; SubsurfaceIndirectRays ss_indirect;
@@ -478,7 +470,7 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
} }
extmax = kernel_data.curve.maximum_width; extmax = kernel_data.curve.maximum_width;
lcg_state = lcg_state_init(rng, state.rng_offset, state.sample, 0x51633e2d); lcg_state = lcg_state_init(&state, 0x51633e2d);
} }
if(state.bounce > kernel_data.integrator.ao_bounces) { if(state.bounce > kernel_data.integrator.ao_bounces) {
@@ -558,15 +550,15 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
int all = false; int all = false;
/* direct light sampling */ /* direct light sampling */
kernel_branched_path_volume_connect_light(kg, rng, &sd, kernel_branched_path_volume_connect_light(kg, &sd,
&emission_sd, throughput, &state, L, all, &emission_sd, throughput, &state, L, all,
&volume_ray, &volume_segment); &volume_ray, &volume_segment);
/* indirect sample. if we use distance sampling and take just /* indirect sample. if we use distance sampling and take just
* one sample for direct and indirect light, we could share * one sample for direct and indirect light, we could share
* this computation, but makes code a bit complex */ * this computation, but makes code a bit complex */
float rphase = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_PHASE); float rphase = path_state_rng_1D_for_decision(kg, &state, PRNG_PHASE);
float rscatter = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_SCATTER_DISTANCE); float rscatter = path_state_rng_1D_for_decision(kg, &state, PRNG_SCATTER_DISTANCE);
result = kernel_volume_decoupled_scatter(kg, result = kernel_volume_decoupled_scatter(kg,
&state, &volume_ray, &sd, &throughput, &state, &volume_ray, &sd, &throughput,
@@ -577,7 +569,7 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
kernel_volume_decoupled_free(kg, &volume_segment); kernel_volume_decoupled_free(kg, &volume_segment);
if(result == VOLUME_PATH_SCATTERED) { if(result == VOLUME_PATH_SCATTERED) {
if(kernel_path_volume_bounce(kg, rng, &sd, &throughput, &state, L, &ray)) if(kernel_path_volume_bounce(kg, &sd, &throughput, &state, L, &ray))
continue; continue;
else else
break; break;
@@ -591,15 +583,15 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
{ {
/* integrate along volume segment with distance sampling */ /* integrate along volume segment with distance sampling */
VolumeIntegrateResult result = kernel_volume_integrate( VolumeIntegrateResult result = kernel_volume_integrate(
kg, &state, &sd, &volume_ray, L, &throughput, rng, heterogeneous); kg, &state, &sd, &volume_ray, L, &throughput, heterogeneous);
# ifdef __VOLUME_SCATTER__ # ifdef __VOLUME_SCATTER__
if(result == VOLUME_PATH_SCATTERED) { if(result == VOLUME_PATH_SCATTERED) {
/* direct lighting */ /* direct lighting */
kernel_path_volume_connect_light(kg, rng, &sd, &emission_sd, throughput, &state, L); kernel_path_volume_connect_light(kg, &sd, &emission_sd, throughput, &state, L);
/* indirect light bounce */ /* indirect light bounce */
if(kernel_path_volume_bounce(kg, rng, &sd, &throughput, &state, L, &ray)) if(kernel_path_volume_bounce(kg, &sd, &throughput, &state, L, &ray))
continue; continue;
else else
break; break;
@@ -634,8 +626,8 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
/* setup shading */ /* setup shading */
shader_setup_from_ray(kg, &sd, &isect, &ray); shader_setup_from_ray(kg, &sd, &isect, &ray);
float rbsdf = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_BSDF); float rbsdf = path_state_rng_1D_for_decision(kg, &state, PRNG_BSDF);
shader_eval_surface(kg, &sd, rng, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN); shader_eval_surface(kg, &sd, &state, rbsdf, state.flag, SHADER_CONTEXT_MAIN);
#ifdef __SHADOW_TRICKS__ #ifdef __SHADOW_TRICKS__
if((sd.object_flag & SD_OBJECT_SHADOW_CATCHER)) { if((sd.object_flag & SD_OBJECT_SHADOW_CATCHER)) {
@@ -713,7 +705,7 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
break; break;
} }
else if(probability != 1.0f) { else if(probability != 1.0f) {
float terminate = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_TERMINATE); float terminate = path_state_rng_1D_for_decision(kg, &state, PRNG_TERMINATE);
if(terminate >= probability) if(terminate >= probability)
break; break;
@@ -725,7 +717,7 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
#ifdef __AO__ #ifdef __AO__
/* ambient occlusion */ /* ambient occlusion */
if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) {
kernel_path_ao(kg, &sd, &emission_sd, L, &state, rng, throughput, shader_bsdf_alpha(kg, &sd)); kernel_path_ao(kg, &sd, &emission_sd, L, &state, throughput, shader_bsdf_alpha(kg, &sd));
} }
#endif /* __AO__ */ #endif /* __AO__ */
@@ -738,7 +730,6 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
&emission_sd, &emission_sd,
L, L,
&state, &state,
rng,
&ray, &ray,
&throughput, &throughput,
&ss_indirect)) &ss_indirect))
@@ -749,10 +740,10 @@ ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
#endif /* __SUBSURFACE__ */ #endif /* __SUBSURFACE__ */
/* direct lighting */ /* direct lighting */
kernel_path_surface_connect_light(kg, rng, &sd, &emission_sd, throughput, &state, L); kernel_path_surface_connect_light(kg, &sd, &emission_sd, throughput, &state, L);
/* compute direct lighting and next bounce */ /* compute direct lighting and next bounce */
if(!kernel_path_surface_bounce(kg, rng, &sd, &throughput, &state, L, &ray)) if(!kernel_path_surface_bounce(kg, &sd, &throughput, &state, L, &ray))
break; break;
} }
@@ -793,17 +784,17 @@ ccl_device void kernel_path_trace(KernelGlobals *kg,
buffer += index*pass_stride; buffer += index*pass_stride;
/* initialize random numbers and ray */ /* initialize random numbers and ray */
RNG rng; uint rng_hash;
Ray ray; Ray ray;
kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng, &ray); kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng_hash, &ray);
/* integrate */ /* integrate */
PathRadiance L; PathRadiance L;
bool is_shadow_catcher; bool is_shadow_catcher;
if(ray.t != 0.0f) { if(ray.t != 0.0f) {
kernel_path_integrate(kg, &rng, sample, ray, buffer, &L, &is_shadow_catcher); kernel_path_integrate(kg, rng_hash, sample, ray, buffer, &L, &is_shadow_catcher);
kernel_write_result(kg, buffer, sample, &L, is_shadow_catcher); kernel_write_result(kg, buffer, sample, &L, is_shadow_catcher);
} }
else { else {

View File

@@ -23,7 +23,6 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg,
ShaderData *emission_sd, ShaderData *emission_sd,
PathRadiance *L, PathRadiance *L,
ccl_addr_space PathState *state, ccl_addr_space PathState *state,
RNG *rng,
float3 throughput) float3 throughput)
{ {
int num_samples = kernel_data.integrator.ao_samples; int num_samples = kernel_data.integrator.ao_samples;
@@ -35,7 +34,7 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg,
for(int j = 0; j < num_samples; j++) { for(int j = 0; j < num_samples; j++) {
float bsdf_u, bsdf_v; float bsdf_u, bsdf_v;
path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v); path_branched_rng_2D(kg, state->rng_hash, state, j, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
float3 ao_D; float3 ao_D;
float ao_pdf; float ao_pdf;
@@ -69,7 +68,7 @@ ccl_device_inline void kernel_branched_path_ao(KernelGlobals *kg,
/* bounce off surface and integrate indirect light */ /* bounce off surface and integrate indirect light */
ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGlobals *kg, ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGlobals *kg,
RNG *rng, ShaderData *sd, ShaderData *indirect_sd, ShaderData *emission_sd, ShaderData *sd, ShaderData *indirect_sd, ShaderData *emission_sd,
float3 throughput, float num_samples_adjust, PathState *state, PathRadiance *L) float3 throughput, float num_samples_adjust, PathState *state, PathRadiance *L)
{ {
float sum_sample_weight = 0.0f; float sum_sample_weight = 0.0f;
@@ -113,7 +112,6 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba
num_samples = ceil_to_int(num_samples_adjust*num_samples); num_samples = ceil_to_int(num_samples_adjust*num_samples);
float num_samples_inv = 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++) { for(int j = 0; j < num_samples; j++) {
PathState ps = *state; PathState ps = *state;
@@ -123,8 +121,9 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba
float shadow_transparency = L->shadow_transparency; float shadow_transparency = L->shadow_transparency;
#endif #endif
ps.rng_hash = cmj_hash(state->rng_hash, i);
if(!kernel_branched_path_surface_bounce(kg, if(!kernel_branched_path_surface_bounce(kg,
&bsdf_rng,
sd, sd,
sc, sc,
j, j,
@@ -138,10 +137,11 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba
continue; continue;
} }
ps.rng_hash = state->rng_hash;
kernel_path_indirect(kg, kernel_path_indirect(kg,
indirect_sd, indirect_sd,
emission_sd, emission_sd,
rng,
&bsdf_ray, &bsdf_ray,
tp*num_samples_inv, tp*num_samples_inv,
num_samples, num_samples,
@@ -167,7 +167,6 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
ShaderData *emission_sd, ShaderData *emission_sd,
PathRadiance *L, PathRadiance *L,
PathState *state, PathState *state,
RNG *rng,
Ray *ray, Ray *ray,
float3 throughput) float3 throughput)
{ {
@@ -178,17 +177,17 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
continue; continue;
/* set up random number generator */ /* set up random number generator */
uint lcg_state = lcg_state_init(rng, state->rng_offset, state->sample, 0x68bc21eb); uint lcg_state = lcg_state_init(state, 0x68bc21eb);
int num_samples = kernel_data.integrator.subsurface_samples; int num_samples = kernel_data.integrator.subsurface_samples;
float num_samples_inv = 1.0f/num_samples; float num_samples_inv = 1.0f/num_samples;
RNG bssrdf_rng = cmj_hash(*rng, i); uint bssrdf_rng_hash = cmj_hash(state->rng_hash, i);
/* do subsurface scatter step with copy of shader data, this will /* do subsurface scatter step with copy of shader data, this will
* replace the BSSRDF with a diffuse BSDF closure */ * replace the BSSRDF with a diffuse BSDF closure */
for(int j = 0; j < num_samples; j++) { for(int j = 0; j < num_samples; j++) {
SubsurfaceIntersection ss_isect; SubsurfaceIntersection ss_isect;
float bssrdf_u, bssrdf_v; float bssrdf_u, bssrdf_v;
path_branched_rng_2D(kg, &bssrdf_rng, state, j, num_samples, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); path_branched_rng_2D(kg, bssrdf_rng_hash, state, j, num_samples, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
int num_hits = subsurface_scatter_multi_intersect(kg, int num_hits = subsurface_scatter_multi_intersect(kg,
&ss_isect, &ss_isect,
sd, sd,
@@ -241,7 +240,6 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
(state->flag & PATH_RAY_SHADOW_CATCHER); (state->flag & PATH_RAY_SHADOW_CATCHER);
kernel_branched_path_surface_connect_light( kernel_branched_path_surface_connect_light(
kg, kg,
rng,
&bssrdf_sd, &bssrdf_sd,
emission_sd, emission_sd,
&hit_state, &hit_state,
@@ -255,7 +253,6 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
/* indirect light */ /* indirect light */
kernel_branched_path_surface_indirect_light( kernel_branched_path_surface_indirect_light(
kg, kg,
rng,
&bssrdf_sd, &bssrdf_sd,
indirect_sd, indirect_sd,
emission_sd, emission_sd,
@@ -270,7 +267,7 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
#endif /* __SUBSURFACE__ */ #endif /* __SUBSURFACE__ */
ccl_device void kernel_branched_path_integrate(KernelGlobals *kg, ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
RNG *rng, uint rng_hash,
int sample, int sample,
Ray ray, Ray ray,
ccl_global float *buffer, ccl_global float *buffer,
@@ -288,7 +285,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
ShaderData emission_sd, indirect_sd; ShaderData emission_sd, indirect_sd;
PathState state; PathState state;
path_state_init(kg, &emission_sd, &state, rng, sample, &ray); path_state_init(kg, &emission_sd, &state, rng_hash, sample, &ray);
/* Main Loop /* Main Loop
* Here we only handle transparency intersections from the camera ray. * Here we only handle transparency intersections from the camera ray.
@@ -311,7 +308,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
} }
extmax = kernel_data.curve.maximum_width; extmax = kernel_data.curve.maximum_width;
lcg_state = lcg_state_init(rng, state.rng_offset, state.sample, 0x51633e2d); lcg_state = lcg_state_init(&state, 0x51633e2d);
} }
bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax); bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax);
@@ -354,7 +351,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
int all = kernel_data.integrator.sample_all_lights_direct; int all = kernel_data.integrator.sample_all_lights_direct;
kernel_branched_path_volume_connect_light(kg, rng, &sd, kernel_branched_path_volume_connect_light(kg, &sd,
&emission_sd, throughput, &state, L, all, &emission_sd, throughput, &state, L, all,
&volume_ray, &volume_segment); &volume_ray, &volume_segment);
@@ -373,8 +370,8 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
/* scatter sample. if we use distance sampling and take just one /* scatter sample. if we use distance sampling and take just one
* sample for direct and indirect light, we could share this * sample for direct and indirect light, we could share this
* computation, but makes code a bit complex */ * computation, but makes code a bit complex */
float rphase = path_state_rng_1D_for_decision(kg, rng, &ps, PRNG_PHASE); float rphase = path_state_rng_1D_for_decision(kg, &ps, PRNG_PHASE);
float rscatter = path_state_rng_1D_for_decision(kg, rng, &ps, PRNG_SCATTER_DISTANCE); float rscatter = path_state_rng_1D_for_decision(kg, &ps, PRNG_SCATTER_DISTANCE);
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
&ps, &pray, &sd, &tp, rphase, rscatter, &volume_segment, NULL, false); &ps, &pray, &sd, &tp, rphase, rscatter, &volume_segment, NULL, false);
@@ -383,7 +380,6 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
kernel_assert(result == VOLUME_PATH_SCATTERED); kernel_assert(result == VOLUME_PATH_SCATTERED);
if(kernel_path_volume_bounce(kg, if(kernel_path_volume_bounce(kg,
rng,
&sd, &sd,
&tp, &tp,
&ps, &ps,
@@ -393,7 +389,6 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
kernel_path_indirect(kg, kernel_path_indirect(kg,
&indirect_sd, &indirect_sd,
&emission_sd, &emission_sd,
rng,
&pray, &pray,
tp*num_samples_inv, tp*num_samples_inv,
num_samples, num_samples,
@@ -432,16 +427,15 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
path_state_branch(&ps, j, num_samples); path_state_branch(&ps, j, num_samples);
VolumeIntegrateResult result = kernel_volume_integrate( VolumeIntegrateResult result = kernel_volume_integrate(
kg, &ps, &sd, &volume_ray, L, &tp, rng, heterogeneous); kg, &ps, &sd, &volume_ray, L, &tp, heterogeneous);
#ifdef __VOLUME_SCATTER__ #ifdef __VOLUME_SCATTER__
if(result == VOLUME_PATH_SCATTERED) { if(result == VOLUME_PATH_SCATTERED) {
/* todo: support equiangular, MIS and all light sampling. /* todo: support equiangular, MIS and all light sampling.
* alternatively get decoupled ray marching working on the GPU */ * alternatively get decoupled ray marching working on the GPU */
kernel_path_volume_connect_light(kg, rng, &sd, &emission_sd, tp, &state, L); kernel_path_volume_connect_light(kg, &sd, &emission_sd, tp, &state, L);
if(kernel_path_volume_bounce(kg, if(kernel_path_volume_bounce(kg,
rng,
&sd, &sd,
&tp, &tp,
&ps, &ps,
@@ -451,7 +445,6 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
kernel_path_indirect(kg, kernel_path_indirect(kg,
&indirect_sd, &indirect_sd,
&emission_sd, &emission_sd,
rng,
&pray, &pray,
tp, tp,
num_samples, num_samples,
@@ -495,7 +488,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
/* setup shading */ /* setup shading */
shader_setup_from_ray(kg, &sd, &isect, &ray); shader_setup_from_ray(kg, &sd, &isect, &ray);
shader_eval_surface(kg, &sd, rng, &state, 0.0f, state.flag, SHADER_CONTEXT_MAIN); shader_eval_surface(kg, &sd, &state, 0.0f, state.flag, SHADER_CONTEXT_MAIN);
shader_merge_closures(&sd); shader_merge_closures(&sd);
#ifdef __SHADOW_TRICKS__ #ifdef __SHADOW_TRICKS__
@@ -558,7 +551,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
break; break;
} }
else if(probability != 1.0f) { else if(probability != 1.0f) {
float terminate = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_TERMINATE); float terminate = path_state_rng_1D_for_decision(kg, &state, PRNG_TERMINATE);
if(terminate >= probability) if(terminate >= probability)
break; break;
@@ -572,7 +565,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
#ifdef __AO__ #ifdef __AO__
/* ambient occlusion */ /* ambient occlusion */
if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) {
kernel_branched_path_ao(kg, &sd, &emission_sd, L, &state, rng, throughput); kernel_branched_path_ao(kg, &sd, &emission_sd, L, &state, throughput);
} }
#endif /* __AO__ */ #endif /* __AO__ */
@@ -580,7 +573,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
/* bssrdf scatter to a different location on the same object */ /* bssrdf scatter to a different location on the same object */
if(sd.flag & SD_BSSRDF) { if(sd.flag & SD_BSSRDF) {
kernel_branched_path_subsurface_scatter(kg, &sd, &indirect_sd, &emission_sd, kernel_branched_path_subsurface_scatter(kg, &sd, &indirect_sd, &emission_sd,
L, &state, rng, &ray, throughput); L, &state, &ray, throughput);
} }
#endif /* __SUBSURFACE__ */ #endif /* __SUBSURFACE__ */
@@ -592,13 +585,13 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
if(kernel_data.integrator.use_direct_light) { if(kernel_data.integrator.use_direct_light) {
int all = (kernel_data.integrator.sample_all_lights_direct) || int all = (kernel_data.integrator.sample_all_lights_direct) ||
(state.flag & PATH_RAY_SHADOW_CATCHER); (state.flag & PATH_RAY_SHADOW_CATCHER);
kernel_branched_path_surface_connect_light(kg, rng, kernel_branched_path_surface_connect_light(kg,
&sd, &emission_sd, &hit_state, throughput, 1.0f, L, all); &sd, &emission_sd, &hit_state, throughput, 1.0f, L, all);
} }
#endif /* __EMISSION__ */ #endif /* __EMISSION__ */
/* indirect light */ /* indirect light */
kernel_branched_path_surface_indirect_light(kg, rng, kernel_branched_path_surface_indirect_light(kg,
&sd, &indirect_sd, &emission_sd, throughput, 1.0f, &hit_state, L); &sd, &indirect_sd, &emission_sd, throughput, 1.0f, &hit_state, L);
/* continue in case of transparency */ /* continue in case of transparency */
@@ -645,17 +638,17 @@ ccl_device void kernel_branched_path_trace(KernelGlobals *kg,
buffer += index*pass_stride; buffer += index*pass_stride;
/* initialize random numbers and ray */ /* initialize random numbers and ray */
RNG rng; uint rng_hash;
Ray ray; Ray ray;
kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng, &ray); kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng_hash, &ray);
/* integrate */ /* integrate */
PathRadiance L; PathRadiance L;
bool is_shadow_catcher; bool is_shadow_catcher;
if(ray.t != 0.0f) { if(ray.t != 0.0f) {
kernel_branched_path_integrate(kg, &rng, sample, ray, buffer, &L, &is_shadow_catcher); kernel_branched_path_integrate(kg, rng_hash, sample, ray, buffer, &L, &is_shadow_catcher);
kernel_write_result(kg, buffer, sample, &L, is_shadow_catcher); kernel_write_result(kg, buffer, sample, &L, is_shadow_catcher);
} }
else { else {

View File

@@ -22,7 +22,7 @@ ccl_device_inline void kernel_path_trace_setup(KernelGlobals *kg,
ccl_global uint *rng_state, ccl_global uint *rng_state,
int sample, int sample,
int x, int y, int x, int y,
RNG *rng, uint *rng_hash,
ccl_addr_space Ray *ray) ccl_addr_space Ray *ray)
{ {
float filter_u; float filter_u;
@@ -34,20 +34,20 @@ ccl_device_inline void kernel_path_trace_setup(KernelGlobals *kg,
*rng_state = hash_int_2d(x, y); *rng_state = hash_int_2d(x, y);
} }
path_rng_init(kg, rng_state, sample, num_samples, rng, x, y, &filter_u, &filter_v); path_rng_init(kg, rng_state, sample, num_samples, rng_hash, x, y, &filter_u, &filter_v);
/* sample camera ray */ /* sample camera ray */
float lens_u = 0.0f, lens_v = 0.0f; float lens_u = 0.0f, lens_v = 0.0f;
if(kernel_data.cam.aperturesize > 0.0f) if(kernel_data.cam.aperturesize > 0.0f)
path_rng_2D(kg, rng, sample, num_samples, PRNG_LENS_U, &lens_u, &lens_v); path_rng_2D(kg, *rng_hash, sample, num_samples, PRNG_LENS_U, &lens_u, &lens_v);
float time = 0.0f; float time = 0.0f;
#ifdef __CAMERA_MOTION__ #ifdef __CAMERA_MOTION__
if(kernel_data.cam.shuttertime != -1.0f) if(kernel_data.cam.shuttertime != -1.0f)
time = path_rng_1D(kg, rng, sample, num_samples, PRNG_TIME); time = path_rng_1D(kg, *rng_hash, sample, num_samples, PRNG_TIME);
#endif #endif
camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, time, ray); camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, time, ray);

View File

@@ -19,12 +19,13 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline void path_state_init(KernelGlobals *kg, ccl_device_inline void path_state_init(KernelGlobals *kg,
ShaderData *stack_sd, ShaderData *stack_sd,
ccl_addr_space PathState *state, ccl_addr_space PathState *state,
RNG *rng, uint rng_hash,
int sample, int sample,
ccl_addr_space Ray *ray) ccl_addr_space Ray *ray)
{ {
state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP; state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP;
state->rng_hash = rng_hash;
state->rng_offset = PRNG_BASE_NUM; state->rng_offset = PRNG_BASE_NUM;
state->sample = sample; state->sample = sample;
state->num_samples = kernel_data.integrator.aa_samples; state->num_samples = kernel_data.integrator.aa_samples;
@@ -58,7 +59,7 @@ ccl_device_inline void path_state_init(KernelGlobals *kg,
/* Initialize volume stack with volume we are inside of. */ /* Initialize volume stack with volume we are inside of. */
kernel_volume_stack_init(kg, stack_sd, state, ray, state->volume_stack); kernel_volume_stack_init(kg, stack_sd, state, ray, state->volume_stack);
/* Seed RNG for cases where we can't use stratified samples .*/ /* Seed RNG for cases where we can't use stratified samples .*/
state->rng_congruential = lcg_init(*rng + sample*0x51633e2d); state->rng_congruential = lcg_init(rng_hash + sample*0x51633e2d);
} }
else { else {
state->volume_stack[0].shader = SHADER_NONE; state->volume_stack[0].shader = SHADER_NONE;

View File

@@ -28,7 +28,6 @@ bool kernel_path_subsurface_scatter(
ShaderData *emission_sd, ShaderData *emission_sd,
PathRadiance *L, PathRadiance *L,
ccl_addr_space PathState *state, ccl_addr_space PathState *state,
RNG *rng,
ccl_addr_space Ray *ray, ccl_addr_space Ray *ray,
ccl_addr_space float3 *throughput, ccl_addr_space float3 *throughput,
ccl_addr_space SubsurfaceIndirectRays *ss_indirect) ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
@@ -47,11 +46,11 @@ bool kernel_path_subsurface_scatter(
*/ */
kernel_assert(!ss_indirect->tracing); kernel_assert(!ss_indirect->tracing);
uint lcg_state = lcg_state_init(rng, state->rng_offset, state->sample, 0x68bc21eb); uint lcg_state = lcg_state_init(state, 0x68bc21eb);
SubsurfaceIntersection ss_isect; SubsurfaceIntersection ss_isect;
float bssrdf_u, bssrdf_v; float bssrdf_u, bssrdf_v;
path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); path_state_rng_2D(kg, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
int num_hits = subsurface_scatter_multi_intersect(kg, int num_hits = subsurface_scatter_multi_intersect(kg,
&ss_isect, &ss_isect,
sd, sd,
@@ -94,10 +93,9 @@ bool kernel_path_subsurface_scatter(
hit_L->direct_throughput = L->direct_throughput; hit_L->direct_throughput = L->direct_throughput;
path_radiance_copy_indirect(hit_L, L); path_radiance_copy_indirect(hit_L, L);
kernel_path_surface_connect_light(kg, rng, sd, emission_sd, *hit_tp, state, hit_L); kernel_path_surface_connect_light(kg, sd, emission_sd, *hit_tp, state, hit_L);
if(kernel_path_surface_bounce(kg, if(kernel_path_surface_bounce(kg,
rng,
sd, sd,
hit_tp, hit_tp,
hit_state, hit_state,

View File

@@ -20,7 +20,6 @@ CCL_NAMESPACE_BEGIN
/* branched path tracing: connect path directly to position on one or more lights and add it to L */ /* branched path tracing: connect path directly to position on one or more lights and add it to L */
ccl_device_noinline void kernel_branched_path_surface_connect_light( ccl_device_noinline void kernel_branched_path_surface_connect_light(
KernelGlobals *kg, KernelGlobals *kg,
RNG *rng,
ShaderData *sd, ShaderData *sd,
ShaderData *emission_sd, ShaderData *emission_sd,
ccl_addr_space PathState *state, ccl_addr_space PathState *state,
@@ -50,12 +49,12 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(
int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i)); int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights); float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
RNG lamp_rng = cmj_hash(*rng, i); uint lamp_rng_hash = cmj_hash(state->rng_hash, i);
for(int j = 0; j < num_samples; j++) { for(int j = 0; j < num_samples; j++) {
float light_u, light_v; float light_u, light_v;
path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); path_branched_rng_2D(kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
float terminate = path_branched_rng_light_termination(kg, &lamp_rng, state, j, num_samples); float terminate = path_branched_rng_light_termination(kg, lamp_rng_hash, state, j, num_samples);
LightSample ls; LightSample ls;
if(lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) { if(lamp_light_sample(kg, i, light_u, light_v, sd->P, &ls)) {
@@ -86,10 +85,10 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(
float num_samples_inv = num_samples_adjust/num_samples; float num_samples_inv = num_samples_adjust/num_samples;
for(int j = 0; j < num_samples; j++) { for(int j = 0; j < num_samples; j++) {
float light_t = path_branched_rng_1D(kg, rng, state, j, num_samples, PRNG_LIGHT); float light_t = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT);
float light_u, light_v; float light_u, light_v;
path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); path_branched_rng_2D(kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
float terminate = path_branched_rng_light_termination(kg, rng, state, j, num_samples); float terminate = path_branched_rng_light_termination(kg, state->rng_hash, state, j, num_samples);
/* only sample triangle lights */ /* only sample triangle lights */
if(kernel_data.integrator.num_all_lights) if(kernel_data.integrator.num_all_lights)
@@ -119,10 +118,10 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(
} }
else { else {
/* sample one light at random */ /* sample one light at random */
float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT); float light_t = path_state_rng_1D(kg, state, PRNG_LIGHT);
float light_u, light_v; float light_u, light_v;
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
float terminate = path_state_rng_light_termination(kg, rng, state); float terminate = path_state_rng_light_termination(kg, state);
LightSample ls; LightSample ls;
if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
@@ -147,7 +146,6 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(
/* branched path tracing: bounce off or through surface to with new direction stored in ray */ /* branched path tracing: bounce off or through surface to with new direction stored in ray */
ccl_device bool kernel_branched_path_surface_bounce( ccl_device bool kernel_branched_path_surface_bounce(
KernelGlobals *kg, KernelGlobals *kg,
RNG *rng,
ShaderData *sd, ShaderData *sd,
const ShaderClosure *sc, const ShaderClosure *sc,
int sample, int sample,
@@ -164,7 +162,7 @@ ccl_device bool kernel_branched_path_surface_bounce(
float3 bsdf_omega_in; float3 bsdf_omega_in;
differential3 bsdf_domega_in; differential3 bsdf_domega_in;
float bsdf_u, bsdf_v; float bsdf_u, bsdf_v;
path_branched_rng_2D(kg, rng, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v); path_branched_rng_2D(kg, state->rng_hash, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
int label; int label;
label = shader_bsdf_sample_closure(kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, label = shader_bsdf_sample_closure(kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval,
@@ -217,7 +215,7 @@ ccl_device bool kernel_branched_path_surface_bounce(
#endif #endif
/* path tracing: connect path directly to position on a light and add it to L */ /* 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, ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg,
ShaderData *sd, ShaderData *emission_sd, float3 throughput, ccl_addr_space PathState *state, ShaderData *sd, ShaderData *emission_sd, float3 throughput, ccl_addr_space PathState *state,
PathRadiance *L) PathRadiance *L)
{ {
@@ -228,7 +226,6 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG
#ifdef __SHADOW_TRICKS__ #ifdef __SHADOW_TRICKS__
if(state->flag & PATH_RAY_SHADOW_CATCHER) { if(state->flag & PATH_RAY_SHADOW_CATCHER) {
kernel_branched_path_surface_connect_light(kg, kernel_branched_path_surface_connect_light(kg,
rng,
sd, sd,
emission_sd, emission_sd,
state, state,
@@ -241,9 +238,9 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG
#endif #endif
/* sample illumination from lights to find path contribution */ /* sample illumination from lights to find path contribution */
float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT); float light_t = path_state_rng_1D(kg, state, PRNG_LIGHT);
float light_u, light_v; float light_u, light_v;
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
Ray light_ray; Ray light_ray;
BsdfEval L_light; BsdfEval L_light;
@@ -255,7 +252,7 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG
LightSample ls; LightSample ls;
if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
float terminate = path_state_rng_light_termination(kg, rng, state); float terminate = path_state_rng_light_termination(kg, state);
if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
/* trace shadow ray */ /* trace shadow ray */
float3 shadow; float3 shadow;
@@ -274,7 +271,6 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG
/* path tracing: bounce off or through surface to with new direction stored in ray */ /* path tracing: bounce off or through surface to with new direction stored in ray */
ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg, ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg,
RNG *rng,
ShaderData *sd, ShaderData *sd,
ccl_addr_space float3 *throughput, ccl_addr_space float3 *throughput,
ccl_addr_space PathState *state, ccl_addr_space PathState *state,
@@ -289,7 +285,7 @@ ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg,
float3 bsdf_omega_in; float3 bsdf_omega_in;
differential3 bsdf_domega_in; differential3 bsdf_domega_in;
float bsdf_u, bsdf_v; float bsdf_u, bsdf_v;
path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
int label; int label;
label = shader_bsdf_sample(kg, sd, bsdf_u, bsdf_v, &bsdf_eval, label = shader_bsdf_sample(kg, sd, bsdf_u, bsdf_v, &bsdf_eval,

View File

@@ -20,7 +20,6 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline void kernel_path_volume_connect_light( ccl_device_inline void kernel_path_volume_connect_light(
KernelGlobals *kg, KernelGlobals *kg,
RNG *rng,
ShaderData *sd, ShaderData *sd,
ShaderData *emission_sd, ShaderData *emission_sd,
float3 throughput, float3 throughput,
@@ -32,9 +31,9 @@ ccl_device_inline void kernel_path_volume_connect_light(
return; return;
/* sample illumination from lights to find path contribution */ /* sample illumination from lights to find path contribution */
float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT); float light_t = path_state_rng_1D(kg, state, PRNG_LIGHT);
float light_u, light_v; float light_u, light_v;
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
Ray light_ray; Ray light_ray;
BsdfEval L_light; BsdfEval L_light;
@@ -48,7 +47,7 @@ ccl_device_inline void kernel_path_volume_connect_light(
if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls))
{ {
float terminate = path_state_rng_light_termination(kg, rng, state); float terminate = path_state_rng_light_termination(kg, state);
if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
/* trace shadow ray */ /* trace shadow ray */
float3 shadow; float3 shadow;
@@ -69,7 +68,6 @@ ccl_device
#endif #endif
bool kernel_path_volume_bounce( bool kernel_path_volume_bounce(
KernelGlobals *kg, KernelGlobals *kg,
RNG *rng,
ShaderData *sd, ShaderData *sd,
ccl_addr_space float3 *throughput, ccl_addr_space float3 *throughput,
ccl_addr_space PathState *state, ccl_addr_space PathState *state,
@@ -82,7 +80,7 @@ bool kernel_path_volume_bounce(
float3 phase_omega_in; float3 phase_omega_in;
differential3 phase_domega_in; differential3 phase_domega_in;
float phase_u, phase_v; float phase_u, phase_v;
path_state_rng_2D(kg, rng, state, PRNG_PHASE_U, &phase_u, &phase_v); path_state_rng_2D(kg, state, PRNG_PHASE_U, &phase_u, &phase_v);
int label; int label;
label = shader_volume_phase_sample(kg, sd, phase_u, phase_v, &phase_eval, label = shader_volume_phase_sample(kg, sd, phase_u, phase_v, &phase_eval,
@@ -120,7 +118,6 @@ bool kernel_path_volume_bounce(
#ifndef __SPLIT_KERNEL__ #ifndef __SPLIT_KERNEL__
ccl_device void kernel_branched_path_volume_connect_light( ccl_device void kernel_branched_path_volume_connect_light(
KernelGlobals *kg, KernelGlobals *kg,
RNG *rng,
ShaderData *sd, ShaderData *sd,
ShaderData *emission_sd, ShaderData *emission_sd,
float3 throughput, float3 throughput,
@@ -150,12 +147,12 @@ ccl_device void kernel_branched_path_volume_connect_light(
int num_samples = light_select_num_samples(kg, i); int num_samples = light_select_num_samples(kg, i);
float num_samples_inv = 1.0f/(num_samples*kernel_data.integrator.num_all_lights); float num_samples_inv = 1.0f/(num_samples*kernel_data.integrator.num_all_lights);
RNG lamp_rng = cmj_hash(*rng, i); uint lamp_rng_hash = cmj_hash(state->rng_hash, i);
for(int j = 0; j < num_samples; j++) { for(int j = 0; j < num_samples; j++) {
/* sample random position on given light */ /* sample random position on given light */
float light_u, light_v; float light_u, light_v;
path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); path_branched_rng_2D(kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
LightSample ls; LightSample ls;
lamp_light_sample(kg, i, light_u, light_v, ray->P, &ls); lamp_light_sample(kg, i, light_u, light_v, ray->P, &ls);
@@ -163,8 +160,8 @@ ccl_device void kernel_branched_path_volume_connect_light(
float3 tp = throughput; float3 tp = throughput;
/* sample position on volume segment */ /* sample position on volume segment */
float rphase = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_PHASE); float rphase = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
float rscatter = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_SCATTER_DISTANCE); float rscatter = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false); state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
@@ -177,7 +174,7 @@ ccl_device void kernel_branched_path_volume_connect_light(
if(kernel_data.integrator.pdf_triangles != 0.0f) if(kernel_data.integrator.pdf_triangles != 0.0f)
ls.pdf *= 2.0f; ls.pdf *= 2.0f;
float terminate = path_branched_rng_light_termination(kg, rng, state, j, num_samples); float terminate = path_branched_rng_light_termination(kg, state->rng_hash, state, j, num_samples);
if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
/* trace shadow ray */ /* trace shadow ray */
float3 shadow; float3 shadow;
@@ -198,9 +195,9 @@ ccl_device void kernel_branched_path_volume_connect_light(
for(int j = 0; j < num_samples; j++) { for(int j = 0; j < num_samples; j++) {
/* sample random position on random triangle */ /* sample random position on random triangle */
float light_t = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_LIGHT); float light_t = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT);
float light_u, light_v; float light_u, light_v;
path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); path_branched_rng_2D(kg, state->rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
/* only sample triangle lights */ /* only sample triangle lights */
if(kernel_data.integrator.num_all_lights) if(kernel_data.integrator.num_all_lights)
@@ -212,8 +209,8 @@ ccl_device void kernel_branched_path_volume_connect_light(
float3 tp = throughput; float3 tp = throughput;
/* sample position on volume segment */ /* sample position on volume segment */
float rphase = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_PHASE); float rphase = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
float rscatter = path_branched_rng_1D_for_decision(kg, rng, state, j, num_samples, PRNG_SCATTER_DISTANCE); float rscatter = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false); state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
@@ -226,7 +223,7 @@ ccl_device void kernel_branched_path_volume_connect_light(
if(kernel_data.integrator.num_all_lights) if(kernel_data.integrator.num_all_lights)
ls.pdf *= 2.0f; ls.pdf *= 2.0f;
float terminate = path_branched_rng_light_termination(kg, rng, state, j, num_samples); float terminate = path_branched_rng_light_termination(kg, state->rng_hash, state, j, num_samples);
if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
/* trace shadow ray */ /* trace shadow ray */
float3 shadow; float3 shadow;
@@ -242,9 +239,9 @@ ccl_device void kernel_branched_path_volume_connect_light(
} }
else { else {
/* sample random position on random light */ /* sample random position on random light */
float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT); float light_t = path_state_rng_1D(kg, state, PRNG_LIGHT);
float light_u, light_v; float light_u, light_v;
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
LightSample ls; LightSample ls;
light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, state->bounce, &ls); light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
@@ -252,8 +249,8 @@ ccl_device void kernel_branched_path_volume_connect_light(
float3 tp = throughput; float3 tp = throughput;
/* sample position on volume segment */ /* sample position on volume segment */
float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE); float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
float rscatter = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE); float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg, VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false); state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
@@ -264,7 +261,7 @@ ccl_device void kernel_branched_path_volume_connect_light(
/* todo: split up light_sample so we don't have to call it again with new position */ /* todo: split up light_sample so we don't have to call it again with new position */
if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
/* sample random light */ /* sample random light */
float terminate = path_state_rng_light_termination(kg, rng, state); float terminate = path_state_rng_light_termination(kg, state);
if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) {
/* trace shadow ray */ /* trace shadow ray */
float3 shadow; float3 shadow;

View File

@@ -52,7 +52,7 @@ ccl_device uint sobol_dimension(KernelGlobals *kg, int index, int dimension)
ccl_device_forceinline float path_rng_1D(KernelGlobals *kg, ccl_device_forceinline float path_rng_1D(KernelGlobals *kg,
RNG *rng, uint rng_hash,
int sample, int num_samples, int sample, int num_samples,
int dimension) int dimension)
{ {
@@ -66,7 +66,7 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals *kg,
# endif # endif
{ {
/* Correlated multi-jitter. */ /* Correlated multi-jitter. */
int p = *rng + dimension; int p = rng_hash + dimension;
return cmj_sample_1D(sample, num_samples, p); return cmj_sample_1D(sample, num_samples, p);
} }
#endif #endif
@@ -82,7 +82,7 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals *kg,
/* Hash rng with dimension to solve correlation issues. /* Hash rng with dimension to solve correlation issues.
* See T38710, T50116. * See T38710, T50116.
*/ */
RNG tmp_rng = cmj_hash_simple(dimension, *rng); uint tmp_rng = cmj_hash_simple(dimension, rng_hash);
shift = tmp_rng * (1.0f/(float)0xFFFFFFFF); shift = tmp_rng * (1.0f/(float)0xFFFFFFFF);
return r + shift - floorf(r + shift); return r + shift - floorf(r + shift);
@@ -90,7 +90,7 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals *kg,
} }
ccl_device_forceinline void path_rng_2D(KernelGlobals *kg, ccl_device_forceinline void path_rng_2D(KernelGlobals *kg,
RNG *rng, uint rng_hash,
int sample, int num_samples, int sample, int num_samples,
int dimension, int dimension,
float *fx, float *fy) float *fx, float *fy)
@@ -107,7 +107,7 @@ ccl_device_forceinline void path_rng_2D(KernelGlobals *kg,
# endif # endif
{ {
/* Correlated multi-jitter. */ /* Correlated multi-jitter. */
int p = *rng + dimension; int p = rng_hash + dimension;
cmj_sample_2D(sample, num_samples, p, fx, fy); cmj_sample_2D(sample, num_samples, p, fx, fy);
return; return;
} }
@@ -115,24 +115,24 @@ ccl_device_forceinline void path_rng_2D(KernelGlobals *kg,
#ifdef __SOBOL__ #ifdef __SOBOL__
/* Sobol. */ /* Sobol. */
*fx = path_rng_1D(kg, rng, sample, num_samples, dimension); *fx = path_rng_1D(kg, rng_hash, sample, num_samples, dimension);
*fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1); *fy = path_rng_1D(kg, rng_hash, sample, num_samples, dimension + 1);
#endif #endif
} }
ccl_device_inline void path_rng_init(KernelGlobals *kg, ccl_device_inline void path_rng_init(KernelGlobals *kg,
ccl_global uint *rng_state, ccl_global uint *rng_state,
int sample, int num_samples, int sample, int num_samples,
RNG *rng, uint *rng_hash,
int x, int y, int x, int y,
float *fx, float *fy) float *fx, float *fy)
{ {
/* load state */ /* load state */
*rng = *rng_state; *rng_hash = *rng_state;
*rng ^= kernel_data.integrator.seed; *rng_hash ^= kernel_data.integrator.seed;
#ifdef __DEBUG_CORRELATION__ #ifdef __DEBUG_CORRELATION__
srand48(*rng + sample); srand48(*rng_hash + sample);
#endif #endif
if(sample == 0) { if(sample == 0) {
@@ -140,7 +140,7 @@ ccl_device_inline void path_rng_init(KernelGlobals *kg,
*fy = 0.5f; *fy = 0.5f;
} }
else { else {
path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U, fx, fy); path_rng_2D(kg, *rng_hash, sample, num_samples, PRNG_FILTER_U, fx, fy);
} }
} }
@@ -177,19 +177,17 @@ ccl_device uint lcg_init(uint seed)
*/ */
ccl_device_inline float path_state_rng_1D(KernelGlobals *kg, ccl_device_inline float path_state_rng_1D(KernelGlobals *kg,
RNG *rng,
const ccl_addr_space PathState *state, const ccl_addr_space PathState *state,
int dimension) int dimension)
{ {
return path_rng_1D(kg, return path_rng_1D(kg,
rng, state->rng_hash,
state->sample, state->num_samples, state->sample, state->num_samples,
state->rng_offset + dimension); state->rng_offset + dimension);
} }
ccl_device_inline float path_state_rng_1D_for_decision( ccl_device_inline float path_state_rng_1D_for_decision(
KernelGlobals *kg, KernelGlobals *kg,
RNG *rng,
const ccl_addr_space PathState *state, const ccl_addr_space PathState *state,
int dimension) int dimension)
{ {
@@ -202,19 +200,18 @@ ccl_device_inline float path_state_rng_1D_for_decision(
* the same decision. */ * the same decision. */
const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM; const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM;
return path_rng_1D(kg, return path_rng_1D(kg,
rng, state->rng_hash,
state->sample, state->num_samples, state->sample, state->num_samples,
rng_offset + dimension); rng_offset + dimension);
} }
ccl_device_inline void path_state_rng_2D(KernelGlobals *kg, ccl_device_inline void path_state_rng_2D(KernelGlobals *kg,
RNG *rng,
const ccl_addr_space PathState *state, const ccl_addr_space PathState *state,
int dimension, int dimension,
float *fx, float *fy) float *fx, float *fy)
{ {
path_rng_2D(kg, path_rng_2D(kg,
rng, state->rng_hash,
state->sample, state->num_samples, state->sample, state->num_samples,
state->rng_offset + dimension, state->rng_offset + dimension,
fx, fy); fx, fy);
@@ -222,14 +219,14 @@ ccl_device_inline void path_state_rng_2D(KernelGlobals *kg,
ccl_device_inline float path_branched_rng_1D( ccl_device_inline float path_branched_rng_1D(
KernelGlobals *kg, KernelGlobals *kg,
RNG *rng, uint rng_hash,
const ccl_addr_space PathState *state, const ccl_addr_space PathState *state,
int branch, int branch,
int num_branches, int num_branches,
int dimension) int dimension)
{ {
return path_rng_1D(kg, return path_rng_1D(kg,
rng, rng_hash,
state->sample * num_branches + branch, state->sample * num_branches + branch,
state->num_samples * num_branches, state->num_samples * num_branches,
state->rng_offset + dimension); state->rng_offset + dimension);
@@ -237,7 +234,7 @@ ccl_device_inline float path_branched_rng_1D(
ccl_device_inline float path_branched_rng_1D_for_decision( ccl_device_inline float path_branched_rng_1D_for_decision(
KernelGlobals *kg, KernelGlobals *kg,
RNG *rng, uint rng_hash,
const ccl_addr_space PathState *state, const ccl_addr_space PathState *state,
int branch, int branch,
int num_branches, int num_branches,
@@ -245,7 +242,7 @@ ccl_device_inline float path_branched_rng_1D_for_decision(
{ {
const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM; const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM;
return path_rng_1D(kg, return path_rng_1D(kg,
rng, rng_hash,
state->sample * num_branches + branch, state->sample * num_branches + branch,
state->num_samples * num_branches, state->num_samples * num_branches,
rng_offset + dimension); rng_offset + dimension);
@@ -253,7 +250,7 @@ ccl_device_inline float path_branched_rng_1D_for_decision(
ccl_device_inline void path_branched_rng_2D( ccl_device_inline void path_branched_rng_2D(
KernelGlobals *kg, KernelGlobals *kg,
RNG *rng, uint rng_hash,
const ccl_addr_space PathState *state, const ccl_addr_space PathState *state,
int branch, int branch,
int num_branches, int num_branches,
@@ -261,7 +258,7 @@ ccl_device_inline void path_branched_rng_2D(
float *fx, float *fy) float *fx, float *fy)
{ {
path_rng_2D(kg, path_rng_2D(kg,
rng, rng_hash,
state->sample * num_branches + branch, state->sample * num_branches + branch,
state->num_samples * num_branches, state->num_samples * num_branches,
state->rng_offset + dimension, state->rng_offset + dimension,
@@ -273,25 +270,24 @@ ccl_device_inline void path_branched_rng_2D(
*/ */
ccl_device_inline float path_state_rng_light_termination( ccl_device_inline float path_state_rng_light_termination(
KernelGlobals *kg, KernelGlobals *kg,
RNG *rng,
const ccl_addr_space PathState *state) const ccl_addr_space PathState *state)
{ {
if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) { if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
return path_state_rng_1D_for_decision(kg, rng, state, PRNG_LIGHT_TERMINATE); return path_state_rng_1D_for_decision(kg, state, PRNG_LIGHT_TERMINATE);
} }
return 0.0f; return 0.0f;
} }
ccl_device_inline float path_branched_rng_light_termination( ccl_device_inline float path_branched_rng_light_termination(
KernelGlobals *kg, KernelGlobals *kg,
RNG *rng, uint rng_hash,
const ccl_addr_space PathState *state, const ccl_addr_space PathState *state,
int branch, int branch,
int num_branches) int num_branches)
{ {
if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) { if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
return path_branched_rng_1D_for_decision(kg, return path_branched_rng_1D_for_decision(kg,
rng, rng_hash,
state, state,
branch, branch,
num_branches, num_branches,
@@ -311,12 +307,10 @@ ccl_device_inline void path_state_branch(ccl_addr_space PathState *state,
state->num_samples = state->num_samples*num_branches; state->num_samples = state->num_samples*num_branches;
} }
ccl_device_inline uint lcg_state_init(RNG *rng, ccl_device_inline uint lcg_state_init(ccl_addr_space PathState *state,
int rng_offset,
int sample,
uint scramble) uint scramble)
{ {
return lcg_init(*rng + rng_offset + sample*scramble); return lcg_init(state->rng_hash + state->rng_offset + state->sample*scramble);
} }
ccl_device float lcg_step_float_addrspace(ccl_addr_space uint *rng) ccl_device float lcg_step_float_addrspace(ccl_addr_space uint *rng)

View File

@@ -863,7 +863,7 @@ ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
/* Surface Evaluation */ /* Surface Evaluation */
ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, RNG *rng, ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
ccl_addr_space PathState *state, float randb, int path_flag, ShaderContext ctx) ccl_addr_space PathState *state, float randb, int path_flag, ShaderContext ctx)
{ {
sd->num_closure = 0; sd->num_closure = 0;
@@ -887,8 +887,8 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, RNG *rng,
#endif #endif
} }
if(rng && (sd->flag & SD_BSDF_NEEDS_LCG)) { if(sd->flag & SD_BSDF_NEEDS_LCG) {
sd->lcg_state = lcg_state_init(rng, state->rng_offset, state->sample, 0xb4bc3953); sd->lcg_state = lcg_state_init(state, 0xb4bc3953);
} }
} }

View File

@@ -49,7 +49,6 @@ ccl_device_forceinline bool shadow_handle_transparent_isect(
path_state_modify_bounce(state, true); path_state_modify_bounce(state, true);
shader_eval_surface(kg, shader_eval_surface(kg,
shadow_sd, shadow_sd,
NULL,
state, state,
0.0f, 0.0f,
PATH_RAY_SHADOW, PATH_RAY_SHADOW,

View File

@@ -219,7 +219,7 @@ ccl_device void subsurface_color_bump_blur(KernelGlobals *kg,
if(bump || texture_blur > 0.0f) { if(bump || texture_blur > 0.0f) {
/* average color and normal at incoming point */ /* average color and normal at incoming point */
shader_eval_surface(kg, sd, NULL, state, 0.0f, state_flag, SHADER_CONTEXT_SSS); shader_eval_surface(kg, sd, state, 0.0f, state_flag, SHADER_CONTEXT_SSS);
float3 in_color = shader_bssrdf_sum(sd, (bump)? N: NULL, NULL); float3 in_color = shader_bssrdf_sum(sd, (bump)? N: NULL, NULL);
/* we simply divide out the average color and multiply with the average /* we simply divide out the average color and multiply with the average
@@ -243,7 +243,7 @@ ccl_device_inline int subsurface_scatter_multi_intersect(
SubsurfaceIntersection *ss_isect, SubsurfaceIntersection *ss_isect,
ShaderData *sd, ShaderData *sd,
ShaderClosure *sc, ShaderClosure *sc,
RNG *lcg_state, uint *lcg_state,
float disk_u, float disk_u,
float disk_v, float disk_v,
bool all) bool all)

View File

@@ -242,10 +242,6 @@ CCL_NAMESPACE_BEGIN
# undef __DENOISING_FEATURES__ # undef __DENOISING_FEATURES__
#endif #endif
/* Random Numbers */
typedef uint RNG;
/* Shader Evaluation */ /* Shader Evaluation */
typedef enum ShaderEvalType { typedef enum ShaderEvalType {
@@ -1023,6 +1019,7 @@ typedef struct PathState {
int flag; int flag;
/* random number generator state */ /* random number generator state */
uint rng_hash; /* per pixel hash */
int rng_offset; /* dimension offset */ int rng_offset; /* dimension offset */
int sample; /* path sample number */ int sample; /* path sample number */
int num_samples; /* total number of times this path will be sampled */ int num_samples; /* total number of times this path will be sampled */
@@ -1048,7 +1045,7 @@ typedef struct PathState {
/* volume rendering */ /* volume rendering */
#ifdef __VOLUME__ #ifdef __VOLUME__
int volume_bounce; int volume_bounce;
RNG rng_congruential; uint rng_congruential;
VolumeStack volume_stack[VOLUME_STACK_SIZE]; VolumeStack volume_stack[VOLUME_STACK_SIZE];
#endif #endif
} PathState; } PathState;

View File

@@ -360,7 +360,6 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(
ShaderData *sd, ShaderData *sd,
PathRadiance *L, PathRadiance *L,
ccl_addr_space float3 *throughput, ccl_addr_space float3 *throughput,
RNG *rng,
bool probalistic_scatter) bool probalistic_scatter)
{ {
VolumeShaderCoefficients coeff; VolumeShaderCoefficients coeff;
@@ -380,13 +379,13 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(
/* pick random color channel, we use the Veach one-sample /* pick random color channel, we use the Veach one-sample
* model with balance heuristic for the channels */ * model with balance heuristic for the channels */
float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE); float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
int channel = (int)(rphase*3.0f); int channel = (int)(rphase*3.0f);
sd->randb_closure = rphase*3.0f - channel; sd->randb_closure = rphase*3.0f - channel;
/* decide if we will hit or miss */ /* decide if we will hit or miss */
bool scatter = true; bool scatter = true;
float xi = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE); float xi = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
if(probalistic_scatter) { if(probalistic_scatter) {
float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel); float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
@@ -468,8 +467,7 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
Ray *ray, Ray *ray,
ShaderData *sd, ShaderData *sd,
PathRadiance *L, PathRadiance *L,
ccl_addr_space float3 *throughput, ccl_addr_space float3 *throughput)
RNG *rng)
{ {
float3 tp = *throughput; float3 tp = *throughput;
const float tp_eps = 1e-6f; /* todo: this is likely not the right value */ const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
@@ -485,8 +483,8 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
/* pick random color channel, we use the Veach one-sample /* pick random color channel, we use the Veach one-sample
* model with balance heuristic for the channels */ * model with balance heuristic for the channels */
float xi = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE); float xi = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE); float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
int channel = (int)(rphase*3.0f); int channel = (int)(rphase*3.0f);
sd->randb_closure = rphase*3.0f - channel; sd->randb_closure = rphase*3.0f - channel;
bool has_scatter = false; bool has_scatter = false;
@@ -610,15 +608,14 @@ ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(
Ray *ray, Ray *ray,
PathRadiance *L, PathRadiance *L,
ccl_addr_space float3 *throughput, ccl_addr_space float3 *throughput,
RNG *rng,
bool heterogeneous) bool heterogeneous)
{ {
shader_setup_from_volume(kg, sd, ray); shader_setup_from_volume(kg, sd, ray);
if(heterogeneous) if(heterogeneous)
return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput, rng); return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput);
else else
return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, rng, true); return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, true);
} }
#ifndef __SPLIT_KERNEL__ #ifndef __SPLIT_KERNEL__

View File

@@ -110,7 +110,6 @@ ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter(
SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index]; SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
ShaderData *sd = saved_sd; ShaderData *sd = saved_sd;
RNG rng = kernel_split_state.rng[ray_index];
PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
float3 throughput = branched_state->throughput; float3 throughput = branched_state->throughput;
ccl_global PathState *ps = &kernel_split_state.path_state[ray_index]; ccl_global PathState *ps = &kernel_split_state.path_state[ray_index];
@@ -157,20 +156,20 @@ ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter(
num_samples = ceil_to_int(num_samples_adjust*num_samples); num_samples = ceil_to_int(num_samples_adjust*num_samples);
float num_samples_inv = num_samples_adjust/num_samples; float num_samples_inv = num_samples_adjust/num_samples;
RNG bsdf_rng = cmj_hash(rng, i);
for(int j = branched_state->next_sample; j < num_samples; j++) { for(int j = branched_state->next_sample; j < num_samples; j++) {
if(reset_path_state) { if(reset_path_state) {
*ps = branched_state->path_state; *ps = branched_state->path_state;
} }
ps->rng_hash = cmj_hash(branched_state->path_state.rng_hash, i);
ccl_global float3 *tp = &kernel_split_state.throughput[ray_index]; ccl_global float3 *tp = &kernel_split_state.throughput[ray_index];
*tp = throughput; *tp = throughput;
ccl_global Ray *bsdf_ray = &kernel_split_state.ray[ray_index]; ccl_global Ray *bsdf_ray = &kernel_split_state.ray[ray_index];
if(!kernel_branched_path_surface_bounce(kg, if(!kernel_branched_path_surface_bounce(kg,
&bsdf_rng,
sd, sd,
sc, sc,
j, j,
@@ -184,6 +183,8 @@ ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter(
continue; continue;
} }
ps->rng_hash = branched_state->path_state.rng_hash;
/* update state for next iteration */ /* update state for next iteration */
branched_state->next_closure = i; branched_state->next_closure = i;
branched_state->next_sample = j+1; branched_state->next_sample = j+1;

View File

@@ -83,7 +83,6 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
ccl_global Ray *ray = &kernel_split_state.ray[ray_index]; ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index]; ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
RNG rng = kernel_split_state.rng[ray_index];
ccl_global float *buffer = kernel_split_params.buffer; ccl_global float *buffer = kernel_split_params.buffer;
unsigned int work_index; unsigned int work_index;
@@ -135,7 +134,8 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
buffer += (kernel_split_params.offset + pixel_x + pixel_y*stride) * kernel_data.film.pass_stride; buffer += (kernel_split_params.offset + pixel_x + pixel_y*stride) * kernel_data.film.pass_stride;
/* Initialize random numbers and ray. */ /* Initialize random numbers and ray. */
kernel_path_trace_setup(kg, rng_state, sample, pixel_x, pixel_y, &rng, ray); uint rng_hash;
kernel_path_trace_setup(kg, rng_state, sample, pixel_x, pixel_y, &rng_hash, ray);
if(ray->t != 0.0f) { if(ray->t != 0.0f) {
/* Initialize throughput, path radiance, Ray, PathState; /* Initialize throughput, path radiance, Ray, PathState;
@@ -143,7 +143,7 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
*/ */
*throughput = make_float3(1.0f, 1.0f, 1.0f); *throughput = make_float3(1.0f, 1.0f, 1.0f);
path_radiance_init(L, kernel_data.film.use_light_pass); path_radiance_init(L, kernel_data.film.use_light_pass);
path_state_init(kg, &kernel_split_state.sd_DL_shadow[ray_index], state, &rng, sample, ray); path_state_init(kg, &kernel_split_state.sd_DL_shadow[ray_index], state, rng_hash, sample, ray);
#ifdef __SUBSURFACE__ #ifdef __SUBSURFACE__
kernel_path_subsurface_init_indirect(&kernel_split_state.ss_rays[ray_index]); kernel_path_subsurface_init_indirect(&kernel_split_state.ss_rays[ray_index]);
#endif #endif
@@ -160,7 +160,6 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
} }
} }
} }
kernel_split_state.rng[ray_index] = rng;
#ifndef __COMPUTE_DEVICE_GPU__ #ifndef __COMPUTE_DEVICE_GPU__
} }

View File

@@ -62,8 +62,6 @@ ccl_device void kernel_direct_lighting(KernelGlobals *kg,
/* direct lighting */ /* direct lighting */
#ifdef __EMISSION__ #ifdef __EMISSION__
RNG rng = kernel_split_state.rng[ray_index];
bool flag = (kernel_data.integrator.use_direct_light && bool flag = (kernel_data.integrator.use_direct_light &&
(sd->flag & SD_BSDF_HAS_EVAL)); (sd->flag & SD_BSDF_HAS_EVAL));
@@ -83,10 +81,10 @@ ccl_device void kernel_direct_lighting(KernelGlobals *kg,
if(flag) { if(flag) {
/* Sample illumination from lights to find path contribution. */ /* Sample illumination from lights to find path contribution. */
float light_t = path_state_rng_1D(kg, &rng, state, PRNG_LIGHT); float light_t = path_state_rng_1D(kg, state, PRNG_LIGHT);
float light_u, light_v; float light_u, light_v;
path_state_rng_2D(kg, &rng, state, PRNG_LIGHT_U, &light_u, &light_v); path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
float terminate = path_state_rng_light_termination(kg, &rng, state); float terminate = path_state_rng_light_termination(kg, state);
LightSample ls; LightSample ls;
if(light_sample(kg, if(light_sample(kg,
@@ -115,7 +113,6 @@ ccl_device void kernel_direct_lighting(KernelGlobals *kg,
} }
} }
} }
kernel_split_state.rng[ray_index] = rng;
#endif /* __EMISSION__ */ #endif /* __EMISSION__ */
} }

View File

@@ -30,7 +30,6 @@ ccl_device_noinline bool kernel_split_branched_path_volume_indirect_light_iter(K
SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index]; SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
ShaderData *sd = &kernel_split_state.sd[ray_index]; ShaderData *sd = &kernel_split_state.sd[ray_index];
RNG rng = kernel_split_state.rng[ray_index];
PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index]; ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
@@ -58,15 +57,15 @@ ccl_device_noinline bool kernel_split_branched_path_volume_indirect_light_iter(K
/* integrate along volume segment with distance sampling */ /* integrate along volume segment with distance sampling */
VolumeIntegrateResult result = kernel_volume_integrate( VolumeIntegrateResult result = kernel_volume_integrate(
kg, ps, sd, &volume_ray, L, tp, &rng, heterogeneous); kg, ps, sd, &volume_ray, L, tp, heterogeneous);
# ifdef __VOLUME_SCATTER__ # ifdef __VOLUME_SCATTER__
if(result == VOLUME_PATH_SCATTERED) { if(result == VOLUME_PATH_SCATTERED) {
/* direct lighting */ /* direct lighting */
kernel_path_volume_connect_light(kg, &rng, sd, emission_sd, *tp, &branched_state->path_state, L); kernel_path_volume_connect_light(kg, sd, emission_sd, *tp, &branched_state->path_state, L);
/* indirect light bounce */ /* indirect light bounce */
if(!kernel_path_volume_bounce(kg, &rng, sd, tp, ps, L, pray)) { if(!kernel_path_volume_bounce(kg, sd, tp, ps, L, pray)) {
continue; continue;
} }
@@ -141,7 +140,6 @@ ccl_device void kernel_do_volume(KernelGlobals *kg)
IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND)) { IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND)) {
ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index]; ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
ccl_global Ray *ray = &kernel_split_state.ray[ray_index]; ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
RNG rng = kernel_split_state.rng[ray_index];
ccl_global Intersection *isect = &kernel_split_state.isect[ray_index]; ccl_global Intersection *isect = &kernel_split_state.isect[ray_index];
ShaderData *sd = &kernel_split_state.sd[ray_index]; ShaderData *sd = &kernel_split_state.sd[ray_index];
ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index]; ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
@@ -165,15 +163,15 @@ ccl_device void kernel_do_volume(KernelGlobals *kg)
{ {
/* integrate along volume segment with distance sampling */ /* integrate along volume segment with distance sampling */
VolumeIntegrateResult result = kernel_volume_integrate( VolumeIntegrateResult result = kernel_volume_integrate(
kg, state, sd, &volume_ray, L, throughput, &rng, heterogeneous); kg, state, sd, &volume_ray, L, throughput, heterogeneous);
# ifdef __VOLUME_SCATTER__ # ifdef __VOLUME_SCATTER__
if(result == VOLUME_PATH_SCATTERED) { if(result == VOLUME_PATH_SCATTERED) {
/* direct lighting */ /* direct lighting */
kernel_path_volume_connect_light(kg, &rng, sd, emission_sd, *throughput, state, L); kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L);
/* indirect light bounce */ /* indirect light bounce */
if(kernel_path_volume_bounce(kg, &rng, sd, throughput, state, L, ray)) { if(kernel_path_volume_bounce(kg, sd, throughput, state, L, ray)) {
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED); ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
} }
else { else {
@@ -194,8 +192,6 @@ ccl_device void kernel_do_volume(KernelGlobals *kg)
} }
# endif /* __BRANCHED_PATH__ */ # endif /* __BRANCHED_PATH__ */
} }
kernel_split_state.rng[ray_index] = rng;
} }
# ifdef __BRANCHED_PATH__ # ifdef __BRANCHED_PATH__

View File

@@ -100,7 +100,6 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
unsigned int tile_y; unsigned int tile_y;
unsigned int sample; unsigned int sample;
RNG rng = kernel_split_state.rng[ray_index];
ccl_global PathState *state = 0x0; ccl_global PathState *state = 0x0;
float3 throughput; float3 throughput;
@@ -247,7 +246,7 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) { if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
if(probability != 1.0f) { if(probability != 1.0f) {
float terminate = path_state_rng_1D_for_decision(kg, &rng, state, PRNG_TERMINATE); float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE);
if(terminate >= probability) { if(terminate >= probability) {
kernel_split_path_end(kg, ray_index); kernel_split_path_end(kg, ray_index);
} }
@@ -269,8 +268,6 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
} }
#endif /* __AO__ */ #endif /* __AO__ */
kernel_split_state.rng[ray_index] = rng;
#ifndef __COMPUTE_DEVICE_GPU__ #ifndef __COMPUTE_DEVICE_GPU__
} }
#endif #endif

View File

@@ -126,7 +126,6 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
if(active) { if(active) {
ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index]; ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
ccl_global Ray *ray = &kernel_split_state.ray[ray_index]; ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
RNG rng = kernel_split_state.rng[ray_index];
ShaderData *sd = &kernel_split_state.sd[ray_index]; ShaderData *sd = &kernel_split_state.sd[ray_index];
ccl_global PathState *state = &kernel_split_state.path_state[ray_index]; ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
@@ -135,7 +134,7 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) { if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
#endif #endif
/* Compute direct lighting and next bounce. */ /* Compute direct lighting and next bounce. */
if(!kernel_path_surface_bounce(kg, &rng, sd, throughput, state, L, ray)) { if(!kernel_path_surface_bounce(kg, sd, throughput, state, L, ray)) {
kernel_split_path_end(kg, ray_index); kernel_split_path_end(kg, ray_index);
} }
#ifdef __BRANCHED_PATH__ #ifdef __BRANCHED_PATH__
@@ -157,8 +156,6 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
} }
} }
#endif /* __BRANCHED_PATH__ */ #endif /* __BRANCHED_PATH__ */
kernel_split_state.rng[ray_index] = rng;
} }
/* Enqueue RAY_UPDATE_BUFFER rays. */ /* Enqueue RAY_UPDATE_BUFFER rays. */

View File

@@ -60,14 +60,14 @@ ccl_device void kernel_path_init(KernelGlobals *kg) {
ccl_global float *buffer = kernel_split_params.buffer; ccl_global float *buffer = kernel_split_params.buffer;
buffer += (kernel_split_params.offset + pixel_x + pixel_y * kernel_split_params.stride) * kernel_data.film.pass_stride; buffer += (kernel_split_params.offset + pixel_x + pixel_y * kernel_split_params.stride) * kernel_data.film.pass_stride;
RNG rng = kernel_split_state.rng[ray_index]; uint rng_hash;
/* Initialize random numbers and ray. */ /* Initialize random numbers and ray. */
kernel_path_trace_setup(kg, kernel_path_trace_setup(kg,
rng_state, rng_state,
my_sample, my_sample,
pixel_x, pixel_y, pixel_x, pixel_y,
&rng, &rng_hash,
&kernel_split_state.ray[ray_index]); &kernel_split_state.ray[ray_index]);
if(kernel_split_state.ray[ray_index].t != 0.0f) { if(kernel_split_state.ray[ray_index].t != 0.0f) {
@@ -79,7 +79,7 @@ ccl_device void kernel_path_init(KernelGlobals *kg) {
path_state_init(kg, path_state_init(kg,
&kernel_split_state.sd_DL_shadow[ray_index], &kernel_split_state.sd_DL_shadow[ray_index],
&kernel_split_state.path_state[ray_index], &kernel_split_state.path_state[ray_index],
&rng, rng_hash,
my_sample, my_sample,
&kernel_split_state.ray[ray_index]); &kernel_split_state.ray[ray_index]);
#ifdef __SUBSURFACE__ #ifdef __SUBSURFACE__
@@ -93,7 +93,6 @@ ccl_device void kernel_path_init(KernelGlobals *kg) {
kernel_write_pass_float4(buffer, my_sample, L_rad); kernel_write_pass_float4(buffer, my_sample, L_rad);
ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE); ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE);
} }
kernel_split_state.rng[ray_index] = rng;
} }
CCL_NAMESPACE_END CCL_NAMESPACE_END

View File

@@ -74,7 +74,6 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg)
#ifdef __HAIR__ #ifdef __HAIR__
float difl = 0.0f, extmax = 0.0f; float difl = 0.0f, extmax = 0.0f;
uint lcg_state = 0; uint lcg_state = 0;
RNG rng = kernel_split_state.rng[ray_index];
if(kernel_data.bvh.have_curves) { if(kernel_data.bvh.have_curves) {
if((kernel_data.cam.resolution == 1) && (state.flag & PATH_RAY_CAMERA)) { if((kernel_data.cam.resolution == 1) && (state.flag & PATH_RAY_CAMERA)) {
@@ -84,7 +83,7 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg)
} }
extmax = kernel_data.curve.maximum_width; extmax = kernel_data.curve.maximum_width;
lcg_state = lcg_state_init(&rng, state.rng_offset, state.sample, 0x51633e2d); lcg_state = lcg_state_init(&state, 0x51633e2d);
} }
bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax); bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax);

View File

@@ -48,18 +48,17 @@ ccl_device void kernel_shader_eval(KernelGlobals *kg)
ccl_global char *ray_state = kernel_split_state.ray_state; ccl_global char *ray_state = kernel_split_state.ray_state;
if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) { if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
RNG rng = kernel_split_state.rng[ray_index];
ccl_global PathState *state = &kernel_split_state.path_state[ray_index]; ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
#ifndef __BRANCHED_PATH__ #ifndef __BRANCHED_PATH__
float rbsdf = path_state_rng_1D_for_decision(kg, &rng, state, PRNG_BSDF); float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
shader_eval_surface(kg, &kernel_split_state.sd[ray_index], &rng, state, rbsdf, state->flag, SHADER_CONTEXT_MAIN); shader_eval_surface(kg, &kernel_split_state.sd[ray_index], state, rbsdf, state->flag, SHADER_CONTEXT_MAIN);
#else #else
ShaderContext ctx = SHADER_CONTEXT_MAIN; ShaderContext ctx = SHADER_CONTEXT_MAIN;
float rbsdf = 0.0f; float rbsdf = 0.0f;
if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) { if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
rbsdf = path_state_rng_1D_for_decision(kg, &rng, state, PRNG_BSDF); rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
} }
@@ -67,11 +66,9 @@ ccl_device void kernel_shader_eval(KernelGlobals *kg)
ctx = SHADER_CONTEXT_INDIRECT; ctx = SHADER_CONTEXT_INDIRECT;
} }
shader_eval_surface(kg, &kernel_split_state.sd[ray_index], &rng, state, rbsdf, state->flag, ctx); shader_eval_surface(kg, &kernel_split_state.sd[ray_index], state, rbsdf, state->flag, ctx);
shader_merge_closures(&kernel_split_state.sd[ray_index]); shader_merge_closures(&kernel_split_state.sd[ray_index]);
#endif /* __BRANCHED_PATH__ */ #endif /* __BRANCHED_PATH__ */
kernel_split_state.rng[ray_index] = rng;
} }
} }

View File

@@ -37,21 +37,18 @@ ccl_device void kernel_shadow_blocked_ao(KernelGlobals *kg)
ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index]; ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
ccl_global PathState *state = &kernel_split_state.path_state[ray_index]; ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
RNG rng = kernel_split_state.rng[ray_index];
float3 throughput = kernel_split_state.throughput[ray_index]; float3 throughput = kernel_split_state.throughput[ray_index];
#ifdef __BRANCHED_PATH__ #ifdef __BRANCHED_PATH__
if(!kernel_data.integrator.branched || IS_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_INDIRECT)) { if(!kernel_data.integrator.branched || IS_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
#endif #endif
kernel_path_ao(kg, sd, emission_sd, L, state, &rng, throughput, shader_bsdf_alpha(kg, sd)); kernel_path_ao(kg, sd, emission_sd, L, state, throughput, shader_bsdf_alpha(kg, sd));
#ifdef __BRANCHED_PATH__ #ifdef __BRANCHED_PATH__
} }
else { else {
kernel_branched_path_ao(kg, sd, emission_sd, L, state, &rng, throughput); kernel_branched_path_ao(kg, sd, emission_sd, L, state, throughput);
} }
#endif #endif
kernel_split_state.rng[ray_index] = rng;
} }
CCL_NAMESPACE_END CCL_NAMESPACE_END

View File

@@ -45,7 +45,6 @@ ccl_device void kernel_shadow_blocked_dl(KernelGlobals *kg)
PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
ShaderData *sd = &kernel_split_state.sd[ray_index]; ShaderData *sd = &kernel_split_state.sd[ray_index];
float3 throughput = kernel_split_state.throughput[ray_index]; float3 throughput = kernel_split_state.throughput[ray_index];
RNG rng = kernel_split_state.rng[ray_index];
BsdfEval L_light = kernel_split_state.bsdf_eval[ray_index]; BsdfEval L_light = kernel_split_state.bsdf_eval[ray_index];
ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index]; ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
@@ -75,7 +74,6 @@ ccl_device void kernel_shadow_blocked_dl(KernelGlobals *kg)
if(use_branched) { if(use_branched) {
kernel_branched_path_surface_connect_light(kg, kernel_branched_path_surface_connect_light(kg,
&rng,
sd, sd,
emission_sd, emission_sd,
state, state,
@@ -103,8 +101,6 @@ ccl_device void kernel_shadow_blocked_dl(KernelGlobals *kg)
path_radiance_accum_total_light(L, state, throughput, &L_light); path_radiance_accum_total_light(L, state, throughput, &L_light);
} }
} }
kernel_split_state.rng[ray_index] = rng;
} }
CCL_NAMESPACE_END CCL_NAMESPACE_END

View File

@@ -114,7 +114,6 @@ typedef ccl_global struct SplitBranchedState {
#endif /* __VOLUME__ */ #endif /* __VOLUME__ */
#define SPLIT_DATA_ENTRIES \ #define SPLIT_DATA_ENTRIES \
SPLIT_DATA_ENTRY(ccl_global RNG, rng, 1) \
SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \ SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \
SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \ SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \
SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \ SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \
@@ -133,7 +132,6 @@ typedef ccl_global struct SplitBranchedState {
/* entries to be copied to inactive rays when sharing branched samples (TODO: which are actually needed?) */ /* entries to be copied to inactive rays when sharing branched samples (TODO: which are actually needed?) */
#define SPLIT_DATA_ENTRIES_BRANCHED_SHARED \ #define SPLIT_DATA_ENTRIES_BRANCHED_SHARED \
SPLIT_DATA_ENTRY(ccl_global RNG, rng, 1) \
SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \ SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \
SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \ SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \
SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \ SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \

View File

@@ -38,7 +38,6 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index]; SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
ShaderData *sd = &branched_state->sd; ShaderData *sd = &branched_state->sd;
RNG rng = kernel_split_state.rng[ray_index];
PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index]; ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
@@ -52,14 +51,12 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
if(branched_state->ss_next_sample == 0 && branched_state->next_hit == 0 && if(branched_state->ss_next_sample == 0 && branched_state->next_hit == 0 &&
branched_state->next_closure == 0 && branched_state->next_sample == 0) branched_state->next_closure == 0 && branched_state->next_sample == 0)
{ {
branched_state->lcg_state = lcg_state_init(&rng, branched_state->lcg_state = lcg_state_init(&branched_state->path_state,
branched_state->path_state.rng_offset,
branched_state->path_state.sample,
0x68bc21eb); 0x68bc21eb);
} }
int num_samples = kernel_data.integrator.subsurface_samples; int num_samples = kernel_data.integrator.subsurface_samples;
float num_samples_inv = 1.0f/num_samples; float num_samples_inv = 1.0f/num_samples;
RNG bssrdf_rng = cmj_hash(rng, i); uint bssrdf_rng_hash = cmj_hash(branched_state->path_state.rng_hash, i);
/* do subsurface scatter step with copy of shader data, this will /* do subsurface scatter step with copy of shader data, this will
* replace the BSSRDF with a diffuse BSDF closure */ * replace the BSSRDF with a diffuse BSDF closure */
@@ -67,7 +64,7 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
ccl_global SubsurfaceIntersection *ss_isect = &branched_state->ss_isect; ccl_global SubsurfaceIntersection *ss_isect = &branched_state->ss_isect;
float bssrdf_u, bssrdf_v; float bssrdf_u, bssrdf_v;
path_branched_rng_2D(kg, path_branched_rng_2D(kg,
&bssrdf_rng, bssrdf_rng_hash,
&branched_state->path_state, &branched_state->path_state,
j, j,
num_samples, num_samples,
@@ -77,7 +74,7 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
/* intersection is expensive so avoid doing multiple times for the same input */ /* intersection is expensive so avoid doing multiple times for the same input */
if(branched_state->next_hit == 0 && branched_state->next_closure == 0 && branched_state->next_sample == 0) { if(branched_state->next_hit == 0 && branched_state->next_closure == 0 && branched_state->next_sample == 0) {
RNG lcg_state = branched_state->lcg_state; uint lcg_state = branched_state->lcg_state;
SubsurfaceIntersection ss_isect_private; SubsurfaceIntersection ss_isect_private;
branched_state->num_hits = subsurface_scatter_multi_intersect(kg, branched_state->num_hits = subsurface_scatter_multi_intersect(kg,
@@ -152,7 +149,6 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it
int all = (kernel_data.integrator.sample_all_lights_direct) || int all = (kernel_data.integrator.sample_all_lights_direct) ||
(branched_state->path_state.flag & PATH_RAY_SHADOW_CATCHER); (branched_state->path_state.flag & PATH_RAY_SHADOW_CATCHER);
kernel_branched_path_surface_connect_light(kg, kernel_branched_path_surface_connect_light(kg,
&rng,
bssrdf_sd, bssrdf_sd,
emission_sd, emission_sd,
hit_state, hit_state,
@@ -229,7 +225,6 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg)
if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) { if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
ccl_global PathState *state = &kernel_split_state.path_state[ray_index]; ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
RNG rng = kernel_split_state.rng[ray_index];
ccl_global Ray *ray = &kernel_split_state.ray[ray_index]; ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index]; ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
ccl_global SubsurfaceIndirectRays *ss_indirect = &kernel_split_state.ss_rays[ray_index]; ccl_global SubsurfaceIndirectRays *ss_indirect = &kernel_split_state.ss_rays[ray_index];
@@ -246,7 +241,6 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg)
emission_sd, emission_sd,
L, L,
state, state,
&rng,
ray, ray,
throughput, throughput,
ss_indirect)) ss_indirect))
@@ -264,10 +258,9 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg)
/* do bssrdf scatter step if we picked a bssrdf closure */ /* do bssrdf scatter step if we picked a bssrdf closure */
if(sc) { if(sc) {
uint lcg_state = lcg_state_init(&rng, state->rng_offset, state->sample, 0x68bc21eb); uint lcg_state = lcg_state_init(state, 0x68bc21eb);
float bssrdf_u, bssrdf_v; float bssrdf_u, bssrdf_v;
path_state_rng_2D(kg, path_state_rng_2D(kg,
&rng,
state, state,
PRNG_BSDF_U, PRNG_BSDF_U,
&bssrdf_u, &bssrdf_v); &bssrdf_u, &bssrdf_v);
@@ -290,7 +283,6 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg)
} }
#endif #endif
} }
kernel_split_state.rng[ray_index] = rng;
} }
# ifdef __BRANCHED_PATH__ # ifdef __BRANCHED_PATH__