forked from bartvdbraak/blender
Fix T40408: world MIS + equiangular sampling giving unnecessary noise.
It's actually not possible to do equiangular sampling for distant lights, now it reverts to distance sampling in this case.
This commit is contained in:
parent
9c9fc626b7
commit
9e61dcc6b8
@ -226,7 +226,7 @@ ccl_device float kernel_volume_equiangular_pdf(Ray *ray, float3 light_P, float s
|
|||||||
return pdf;
|
return pdf;
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device bool kernel_volume_equiangular_light_position(KernelGlobals *kg, PathState *state, Ray *ray, RNG *rng, float3 *light_P)
|
ccl_device bool kernel_volume_equiangular_light_position(KernelGlobals *kg, PathState *state, Ray *ray, RNG *rng, float3 *light_P, bool *distant)
|
||||||
{
|
{
|
||||||
/* light RNGs */
|
/* light RNGs */
|
||||||
float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
|
float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
|
||||||
@ -240,19 +240,11 @@ ccl_device bool kernel_volume_equiangular_light_position(KernelGlobals *kg, Path
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
*light_P = ls.P;
|
*light_P = ls.P;
|
||||||
|
*distant = ls.t == FLT_MAX;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device float kernel_volume_decoupled_equiangular_pdf(KernelGlobals *kg, PathState *state, Ray *ray, RNG *rng, float sample_t)
|
|
||||||
{
|
|
||||||
float3 light_P;
|
|
||||||
|
|
||||||
if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P))
|
|
||||||
return 0.0f;
|
|
||||||
|
|
||||||
return kernel_volume_equiangular_pdf(ray, light_P, sample_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Distance sampling */
|
/* Distance sampling */
|
||||||
|
|
||||||
ccl_device float kernel_volume_distance_sample(float max_t, float3 sigma_t, int channel, float xi, float3 *transmittance, float3 *pdf)
|
ccl_device float kernel_volume_distance_sample(float max_t, float3 sigma_t, int channel, float xi, float3 *transmittance, float3 *pdf)
|
||||||
@ -357,13 +349,21 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba
|
|||||||
/* equiangular sampling */
|
/* equiangular sampling */
|
||||||
float3 light_P;
|
float3 light_P;
|
||||||
float equi_pdf;
|
float equi_pdf;
|
||||||
if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P))
|
bool light_distant;
|
||||||
|
|
||||||
|
if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P, &light_distant))
|
||||||
return VOLUME_PATH_MISSED;
|
return VOLUME_PATH_MISSED;
|
||||||
|
|
||||||
|
if(light_distant) {
|
||||||
|
/* distant light, revert to distance sampling because position is infinitely far away */
|
||||||
|
sample_t = kernel_volume_distance_sample(ray->t, sigma_t, channel, xi, &transmittance, &pdf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
sample_t = kernel_volume_equiangular_sample(ray, light_P, xi, &equi_pdf);
|
sample_t = kernel_volume_equiangular_sample(ray, light_P, xi, &equi_pdf);
|
||||||
transmittance = volume_color_transmittance(sigma_t, sample_t);
|
transmittance = volume_color_transmittance(sigma_t, sample_t);
|
||||||
pdf = make_float3(equi_pdf, equi_pdf, equi_pdf);
|
pdf = make_float3(equi_pdf, equi_pdf, equi_pdf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* modifiy pdf for hit/miss decision */
|
/* modifiy pdf for hit/miss decision */
|
||||||
pdf *= make_float3(1.0f, 1.0f, 1.0f) - volume_color_transmittance(sigma_t, t);
|
pdf *= make_float3(1.0f, 1.0f, 1.0f) - volume_color_transmittance(sigma_t, t);
|
||||||
@ -720,8 +720,23 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
|
|||||||
float3 transmittance;
|
float3 transmittance;
|
||||||
float pdf, sample_t;
|
float pdf, sample_t;
|
||||||
|
|
||||||
|
/* pick position on light for equiangular */
|
||||||
|
bool equiangular = (kernel_data.integrator.volume_homogeneous_sampling != 0 && kernel_data.integrator.num_all_lights);
|
||||||
|
float3 light_P;
|
||||||
|
|
||||||
|
if(equiangular) {
|
||||||
|
bool light_distant;
|
||||||
|
|
||||||
|
if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P, &light_distant))
|
||||||
|
return VOLUME_PATH_MISSED;
|
||||||
|
|
||||||
|
/* distant light, revert to distance sampling because position is infinitely far away */
|
||||||
|
if(light_distant)
|
||||||
|
equiangular = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* distance sampling */
|
/* distance sampling */
|
||||||
if(kernel_data.integrator.volume_homogeneous_sampling == 0 || !kernel_data.integrator.num_all_lights) {
|
if(!equiangular) {
|
||||||
/* find step in cdf */
|
/* find step in cdf */
|
||||||
step = segment->steps;
|
step = segment->steps;
|
||||||
|
|
||||||
@ -762,11 +777,6 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
|
|||||||
}
|
}
|
||||||
/* equi-angular sampling */
|
/* equi-angular sampling */
|
||||||
else {
|
else {
|
||||||
/* pick position on light */
|
|
||||||
float3 light_P;
|
|
||||||
if(!kernel_volume_equiangular_light_position(kg, state, ray, rng, &light_P))
|
|
||||||
return VOLUME_PATH_MISSED;
|
|
||||||
|
|
||||||
/* sample distance */
|
/* sample distance */
|
||||||
sample_t = kernel_volume_equiangular_sample(ray, light_P, xi, &pdf);
|
sample_t = kernel_volume_equiangular_sample(ray, light_P, xi, &pdf);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user