Cycles volume: change homogeneous volume sampling in branched path first hit.
Similar to surfaces, this will now always scatter rather than probabilistically scattering or not depending on the transmittance. This also makes calculation of branched path throughput non-probalistic, which makes thing slower too. That's to be solved by decoupled ray marching later.
This commit is contained in:
@@ -261,7 +261,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_g
|
||||
|
||||
ShaderData volume_sd;
|
||||
VolumeIntegrateResult result = kernel_volume_integrate(kg, &state,
|
||||
&volume_sd, &volume_ray, L, &throughput, rng);
|
||||
&volume_sd, &volume_ray, L, &throughput, rng, false);
|
||||
|
||||
if(result == VOLUME_PATH_SCATTERED) {
|
||||
if(kernel_path_integrate_scatter_lighting(kg, rng, &volume_sd, &throughput, &state, L, &ray, 1.0f))
|
||||
@@ -650,7 +650,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
|
||||
|
||||
ShaderData volume_sd;
|
||||
VolumeIntegrateResult result = kernel_volume_integrate(kg, &state,
|
||||
&volume_sd, &volume_ray, &L, &throughput, rng);
|
||||
&volume_sd, &volume_ray, &L, &throughput, rng, false);
|
||||
|
||||
if(result == VOLUME_PATH_SCATTERED) {
|
||||
if(kernel_path_integrate_scatter_lighting(kg, rng, &volume_sd, &throughput, &state, &L, &ray, 1.0f))
|
||||
@@ -1092,7 +1092,6 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
|
||||
|
||||
int num_samples = kernel_data.integrator.volume_samples;
|
||||
float num_samples_inv = 1.0f/num_samples;
|
||||
float3 avg_tp = make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
/* todo: we should cache the shader evaluations from stepping
|
||||
* through the volume, for now we redo them multiple times */
|
||||
@@ -1107,7 +1106,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
|
||||
path_state_branch(&ps, j, num_samples);
|
||||
|
||||
VolumeIntegrateResult result = kernel_volume_integrate(kg, &ps,
|
||||
&volume_sd, &volume_ray, &L, &tp, rng);
|
||||
&volume_sd, &volume_ray, &L, &tp, rng, true);
|
||||
|
||||
if(result == VOLUME_PATH_SCATTERED) {
|
||||
/* todo: use all-light sampling */
|
||||
@@ -1120,11 +1119,10 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
|
||||
path_radiance_reset_indirect(&L);
|
||||
}
|
||||
}
|
||||
else
|
||||
avg_tp += tp;
|
||||
}
|
||||
|
||||
throughput = avg_tp * num_samples_inv;
|
||||
/* todo: avoid this calculation using decoupled ray marching */
|
||||
kernel_volume_shadow(kg, &state, &volume_ray, &throughput);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -295,7 +295,7 @@ ccl_device float3 kernel_volume_emission_integrate(VolumeShaderCoefficients *coe
|
||||
* the volume shading coefficient for the entire line segment */
|
||||
ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGlobals *kg,
|
||||
PathState *state, Ray *ray, ShaderData *sd, PathRadiance *L, float3 *throughput,
|
||||
RNG *rng)
|
||||
RNG *rng, bool branched)
|
||||
{
|
||||
VolumeShaderCoefficients coeff;
|
||||
|
||||
@@ -318,19 +318,14 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba
|
||||
int channel = (int)(rphase*3.0f);
|
||||
sd->randb_closure = rphase*3.0f - channel;
|
||||
|
||||
/* decide if we will hit or miss */
|
||||
float xi = path_state_rng_1D(kg, rng, state, PRNG_SCATTER_DISTANCE);
|
||||
float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
|
||||
float sample_transmittance = expf(-sample_sigma_t * t);
|
||||
|
||||
if(xi >= sample_transmittance) {
|
||||
/* scattering */
|
||||
if(branched) {
|
||||
/* branched path tracing: we always scatter in the segment */
|
||||
float3 pdf;
|
||||
float sample_t;
|
||||
|
||||
/* rescale random number so we can reuse it */
|
||||
xi = (xi - sample_transmittance)/(1.0f - sample_transmittance);
|
||||
|
||||
/* scattering */
|
||||
if(kernel_data.integrator.volume_homogeneous_sampling == 0 || !kernel_data.integrator.num_all_lights) {
|
||||
/* distance sampling */
|
||||
sample_t = kernel_volume_distance_sample(ray, sigma_t, channel, xi, &transmittance, &pdf);
|
||||
@@ -346,17 +341,52 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba
|
||||
pdf = make_float3(equi_pdf, equi_pdf, equi_pdf);
|
||||
}
|
||||
|
||||
/* modifiy pdf for hit/miss decision */
|
||||
pdf *= make_float3(1.0f, 1.0f, 1.0f) - volume_color_transmittance(sigma_t, t);
|
||||
|
||||
new_tp = *throughput * coeff.sigma_s * transmittance / ((pdf.x + pdf.y + pdf.z) * (1.0f/3.0f));
|
||||
t = sample_t;
|
||||
}
|
||||
else {
|
||||
/* no scattering */
|
||||
transmittance = volume_color_transmittance(sigma_t, t);
|
||||
float pdf = (transmittance.x + transmittance.y + transmittance.z) * (1.0f/3.0f);
|
||||
new_tp = *throughput * transmittance / pdf;
|
||||
/* regular path tracing: we probalistically scatter in the segment
|
||||
* with probability the transmittance over the segment */
|
||||
|
||||
/* decide if we will hit or miss */
|
||||
float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
|
||||
float sample_transmittance = expf(-sample_sigma_t * t);
|
||||
|
||||
if(xi >= sample_transmittance) {
|
||||
/* scattering */
|
||||
float3 pdf;
|
||||
float sample_t;
|
||||
|
||||
/* rescale random number so we can reuse it */
|
||||
xi = (xi - sample_transmittance)/(1.0f - sample_transmittance);
|
||||
|
||||
if(kernel_data.integrator.volume_homogeneous_sampling == 0 || !kernel_data.integrator.num_all_lights) {
|
||||
/* distance sampling */
|
||||
sample_t = kernel_volume_distance_sample(ray, sigma_t, channel, xi, &transmittance, &pdf);
|
||||
}
|
||||
else {
|
||||
/* equiangular sampling */
|
||||
float3 light_P;
|
||||
float equi_pdf;
|
||||
if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P))
|
||||
return VOLUME_PATH_MISSED;
|
||||
|
||||
sample_t = kernel_volume_equiangular_sample(ray, sigma_t, light_P, xi, &transmittance, &equi_pdf);
|
||||
pdf = make_float3(equi_pdf, equi_pdf, equi_pdf);
|
||||
}
|
||||
|
||||
/* modifiy pdf for hit/miss decision */
|
||||
pdf *= make_float3(1.0f, 1.0f, 1.0f) - volume_color_transmittance(sigma_t, t);
|
||||
|
||||
new_tp = *throughput * coeff.sigma_s * transmittance / ((pdf.x + pdf.y + pdf.z) * (1.0f/3.0f));
|
||||
t = sample_t;
|
||||
}
|
||||
else {
|
||||
/* no scattering */
|
||||
transmittance = volume_color_transmittance(sigma_t, t);
|
||||
float pdf = (transmittance.x + transmittance.y + transmittance.z) * (1.0f/3.0f);
|
||||
new_tp = *throughput * transmittance / pdf;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(closure_flag & SD_ABSORPTION) {
|
||||
@@ -547,7 +577,8 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous(KernelGlo
|
||||
* ray, with the assumption that there are no surfaces blocking light
|
||||
* between the endpoints */
|
||||
ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals *kg,
|
||||
PathState *state, ShaderData *sd, Ray *ray, PathRadiance *L, float3 *throughput, RNG *rng)
|
||||
PathState *state, ShaderData *sd, Ray *ray, PathRadiance *L, float3 *throughput, RNG *rng,
|
||||
bool branched)
|
||||
{
|
||||
/* workaround to fix correlation bug in T38710, can find better solution
|
||||
* in random number generator later, for now this is done here to not impact
|
||||
@@ -560,7 +591,7 @@ ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals
|
||||
if(heterogeneous)
|
||||
return kernel_volume_integrate_heterogeneous(kg, state, ray, sd, L, throughput, &tmp_rng);
|
||||
else
|
||||
return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, &tmp_rng);
|
||||
return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, &tmp_rng, branched);
|
||||
}
|
||||
|
||||
/* Volume Stack
|
||||
|
Reference in New Issue
Block a user