Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2014-05-29 15:20:42 +0400
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2014-05-29 16:50:47 +0400
commit9e61dcc6b89f21420bf64c25741c3a259c4158ba (patch)
tree3a2f80b046eefc7ff7034e6e82da05f1ad908206 /intern/cycles/kernel/kernel_volume.h
parent9c9fc626b7e6c4bf08a667d56b6718b8426bf576 (diff)
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.
Diffstat (limited to 'intern/cycles/kernel/kernel_volume.h')
-rw-r--r--intern/cycles/kernel/kernel_volume.h52
1 files changed, 31 insertions, 21 deletions
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index faaa68e3309..75c81940bbb 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -226,7 +226,7 @@ ccl_device float kernel_volume_equiangular_pdf(Ray *ray, float3 light_P, float s
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 */
float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
@@ -240,17 +240,9 @@ ccl_device bool kernel_volume_equiangular_light_position(KernelGlobals *kg, Path
return false;
*light_P = ls.P;
- return true;
-}
-
-ccl_device float kernel_volume_decoupled_equiangular_pdf(KernelGlobals *kg, PathState *state, Ray *ray, RNG *rng, float sample_t)
-{
- float3 light_P;
+ *distant = ls.t == FLT_MAX;
- 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);
+ return true;
}
/* Distance sampling */
@@ -357,12 +349,20 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba
/* equiangular sampling */
float3 light_P;
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;
- sample_t = kernel_volume_equiangular_sample(ray, light_P, xi, &equi_pdf);
- transmittance = volume_color_transmittance(sigma_t, sample_t);
- pdf = make_float3(equi_pdf, equi_pdf, equi_pdf);
+ 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);
+ transmittance = volume_color_transmittance(sigma_t, sample_t);
+ pdf = make_float3(equi_pdf, equi_pdf, equi_pdf);
+ }
}
/* modifiy pdf for hit/miss decision */
@@ -720,8 +720,23 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
float3 transmittance;
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 */
- if(kernel_data.integrator.volume_homogeneous_sampling == 0 || !kernel_data.integrator.num_all_lights) {
+ if(!equiangular) {
/* find step in cdf */
step = segment->steps;
@@ -762,11 +777,6 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
}
/* equi-angular sampling */
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_t = kernel_volume_equiangular_sample(ray, light_P, xi, &pdf);