forked from bartvdbraak/blender
Code cleanup: remove hack to avoid seeing transparent objects in noise.
Previously the Sobol pattern suffered from some correlation issues that made the outline of objects like a smoke domain visible. This helps simplify the code and also makes some other optimizations possible.
This commit is contained in:
parent
8289b47e3a
commit
d750d182e5
@ -210,8 +210,8 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(
|
|||||||
/* 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, state, PRNG_PHASE);
|
float rphase = path_state_rng_1D(kg, state, PRNG_PHASE);
|
||||||
float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
|
float rscatter = path_state_rng_1D(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,
|
||||||
@ -434,7 +434,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
|
|||||||
sd,
|
sd,
|
||||||
&isect,
|
&isect,
|
||||||
ray);
|
ray);
|
||||||
float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
|
float rbsdf = path_state_rng_1D(kg, state, PRNG_BSDF);
|
||||||
shader_eval_surface(kg, sd, state, rbsdf, state->flag);
|
shader_eval_surface(kg, sd, state, rbsdf, state->flag);
|
||||||
#ifdef __BRANCHED_PATH__
|
#ifdef __BRANCHED_PATH__
|
||||||
shader_merge_closures(sd);
|
shader_merge_closures(sd);
|
||||||
@ -462,7 +462,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, state, PRNG_TERMINATE);
|
float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
|
||||||
|
|
||||||
if(terminate >= probability)
|
if(terminate >= probability)
|
||||||
break;
|
break;
|
||||||
@ -591,7 +591,7 @@ ccl_device_forceinline void kernel_path_integrate(
|
|||||||
|
|
||||||
/* Setup and evaluate shader. */
|
/* Setup and evaluate shader. */
|
||||||
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, state, PRNG_BSDF);
|
float rbsdf = path_state_rng_1D(kg, state, PRNG_BSDF);
|
||||||
shader_eval_surface(kg, &sd, state, rbsdf, state->flag);
|
shader_eval_surface(kg, &sd, state, rbsdf, state->flag);
|
||||||
|
|
||||||
/* Apply shadow catcher, holdout, emission. */
|
/* Apply shadow catcher, holdout, emission. */
|
||||||
@ -616,7 +616,7 @@ ccl_device_forceinline void kernel_path_integrate(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if(probability != 1.0f) {
|
else if(probability != 1.0f) {
|
||||||
float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE);
|
float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
|
||||||
if(terminate >= probability)
|
if(terminate >= probability)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -339,8 +339,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, &ps, PRNG_PHASE);
|
float rphase = path_state_rng_1D(kg, &ps, PRNG_PHASE);
|
||||||
float rscatter = path_state_rng_1D_for_decision(kg, &ps, PRNG_SCATTER_DISTANCE);
|
float rscatter = path_state_rng_1D(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);
|
||||||
@ -466,7 +466,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, &state, PRNG_TERMINATE);
|
float terminate = path_state_rng_1D(kg, &state, PRNG_TERMINATE);
|
||||||
|
|
||||||
if(terminate >= probability)
|
if(terminate >= probability)
|
||||||
break;
|
break;
|
||||||
|
@ -76,12 +76,12 @@ ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathSta
|
|||||||
state->flag |= PATH_RAY_TRANSPARENT;
|
state->flag |= PATH_RAY_TRANSPARENT;
|
||||||
state->transparent_bounce++;
|
state->transparent_bounce++;
|
||||||
|
|
||||||
/* don't increase random number generator offset here, to avoid some
|
|
||||||
* unwanted patterns, see path_state_rng_1D_for_decision */
|
|
||||||
|
|
||||||
if(!kernel_data.integrator.transparent_shadows)
|
if(!kernel_data.integrator.transparent_shadows)
|
||||||
state->flag |= PATH_RAY_MIS_SKIP;
|
state->flag |= PATH_RAY_MIS_SKIP;
|
||||||
|
|
||||||
|
/* random number generator next bounce */
|
||||||
|
state->rng_offset += PRNG_BOUNCE_NUM;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,8 +155,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, state->rng_hash, state, j, num_samples, PRNG_PHASE);
|
float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
|
||||||
float rscatter = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
|
float rscatter = path_branched_rng_1D(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);
|
||||||
@ -201,8 +201,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, state->rng_hash, state, j, num_samples, PRNG_PHASE);
|
float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
|
||||||
float rscatter = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
|
float rscatter = path_branched_rng_1D(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);
|
||||||
@ -238,8 +238,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, state, PRNG_PHASE);
|
float rphase = path_state_rng_1D(kg, state, PRNG_PHASE);
|
||||||
float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
|
float rscatter = path_state_rng_1D(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);
|
||||||
|
@ -186,25 +186,6 @@ ccl_device_inline float path_state_rng_1D(KernelGlobals *kg,
|
|||||||
state->rng_offset + dimension);
|
state->rng_offset + dimension);
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device_inline float path_state_rng_1D_for_decision(
|
|
||||||
KernelGlobals *kg,
|
|
||||||
const ccl_addr_space PathState *state,
|
|
||||||
int dimension)
|
|
||||||
{
|
|
||||||
/* The rng_offset is not increased for transparent bounces. if we do then
|
|
||||||
* fully transparent objects can become subtly visible by the different
|
|
||||||
* sampling patterns used where the transparent object is.
|
|
||||||
*
|
|
||||||
* however for some random numbers that will determine if we next bounce
|
|
||||||
* is transparent we do need to increase the offset to avoid always making
|
|
||||||
* the same decision. */
|
|
||||||
const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM;
|
|
||||||
return path_rng_1D(kg,
|
|
||||||
state->rng_hash,
|
|
||||||
state->sample, state->num_samples,
|
|
||||||
rng_offset + dimension);
|
|
||||||
}
|
|
||||||
|
|
||||||
ccl_device_inline void path_state_rng_2D(KernelGlobals *kg,
|
ccl_device_inline void path_state_rng_2D(KernelGlobals *kg,
|
||||||
const ccl_addr_space PathState *state,
|
const ccl_addr_space PathState *state,
|
||||||
int dimension,
|
int dimension,
|
||||||
@ -232,22 +213,6 @@ ccl_device_inline float path_branched_rng_1D(
|
|||||||
state->rng_offset + dimension);
|
state->rng_offset + dimension);
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device_inline float path_branched_rng_1D_for_decision(
|
|
||||||
KernelGlobals *kg,
|
|
||||||
uint rng_hash,
|
|
||||||
const ccl_addr_space PathState *state,
|
|
||||||
int branch,
|
|
||||||
int num_branches,
|
|
||||||
int dimension)
|
|
||||||
{
|
|
||||||
const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM;
|
|
||||||
return path_rng_1D(kg,
|
|
||||||
rng_hash,
|
|
||||||
state->sample * num_branches + branch,
|
|
||||||
state->num_samples * num_branches,
|
|
||||||
rng_offset + dimension);
|
|
||||||
}
|
|
||||||
|
|
||||||
ccl_device_inline void path_branched_rng_2D(
|
ccl_device_inline void path_branched_rng_2D(
|
||||||
KernelGlobals *kg,
|
KernelGlobals *kg,
|
||||||
uint rng_hash,
|
uint rng_hash,
|
||||||
@ -273,7 +238,7 @@ ccl_device_inline float path_state_rng_light_termination(
|
|||||||
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, state, PRNG_LIGHT_TERMINATE);
|
return path_state_rng_1D(kg, state, PRNG_LIGHT_TERMINATE);
|
||||||
}
|
}
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
@ -286,12 +251,12 @@ ccl_device_inline float path_branched_rng_light_termination(
|
|||||||
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(kg,
|
||||||
rng_hash,
|
rng_hash,
|
||||||
state,
|
state,
|
||||||
branch,
|
branch,
|
||||||
num_branches,
|
num_branches,
|
||||||
PRNG_LIGHT_TERMINATE);
|
PRNG_LIGHT_TERMINATE);
|
||||||
}
|
}
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
@ -379,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, state, PRNG_PHASE);
|
float rphase = path_state_rng_1D(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, state, PRNG_SCATTER_DISTANCE);
|
float xi = path_state_rng_1D(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);
|
||||||
@ -483,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, state, PRNG_SCATTER_DISTANCE);
|
float xi = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
|
||||||
float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
|
float rphase = path_state_rng_1D(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;
|
||||||
|
@ -140,7 +140,7 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
|
|||||||
kernel_split_path_end(kg, ray_index);
|
kernel_split_path_end(kg, ray_index);
|
||||||
}
|
}
|
||||||
else if(probability < 1.0f) {
|
else if(probability < 1.0f) {
|
||||||
float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE);
|
float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
|
||||||
if(terminate >= probability) {
|
if(terminate >= probability) {
|
||||||
kernel_split_path_end(kg, ray_index);
|
kernel_split_path_end(kg, ray_index);
|
||||||
}
|
}
|
||||||
|
@ -51,13 +51,13 @@ ccl_device void kernel_shader_eval(KernelGlobals *kg)
|
|||||||
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, state, PRNG_BSDF);
|
float rbsdf = path_state_rng_1D(kg, state, PRNG_BSDF);
|
||||||
shader_eval_surface(kg, &kernel_split_state.sd[ray_index], state, rbsdf, state->flag);
|
shader_eval_surface(kg, &kernel_split_state.sd[ray_index], state, rbsdf, state->flag);
|
||||||
#else
|
#else
|
||||||
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, state, PRNG_BSDF);
|
rbsdf = path_state_rng_1D(kg, state, PRNG_BSDF);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user