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:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-11-24 18:37:27 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-11-24 18:39:02 +0300
commit729affe7c99a3fef892ec0810fc89dbead10db8e (patch)
treef00a3efcc7e45852215ed6f524da7e9d793bb4c0 /intern/cycles
parent4d3d2d02993488dda03094ecc580fe26ebec4f39 (diff)
Cycles: Avoid divisions by zero in volume sampling code
Was giving huge artifacts in the barber shop file here in the studio, Maybe not fully optimal solution, but committing it for now to have closer look later.
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/kernel/kernel_volume.h22
1 files changed, 19 insertions, 3 deletions
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index 0f45b0e7d60..dd7b0d9812d 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -245,11 +245,18 @@ ccl_device float kernel_volume_equiangular_sample(Ray *ray, float3 light_P, floa
float t = ray->t;
float delta = dot((light_P - ray->P) , ray->D);
- float D = sqrtf(len_squared(light_P - ray->P) - delta * delta);
+ float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
+ if(UNLIKELY(D == 0.0f)) {
+ *pdf = 0.0f;
+ return 0.0f;
+ }
float theta_a = -atan2f(delta, D);
float theta_b = atan2f(t - delta, D);
float t_ = D * tanf((xi * theta_b) + (1 - xi) * theta_a);
-
+ if(UNLIKELY(theta_b == theta_a)) {
+ *pdf = 0.0f;
+ return 0.0f;
+ }
*pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
return min(t, delta + t_); /* min is only for float precision errors */
@@ -258,13 +265,19 @@ ccl_device float kernel_volume_equiangular_sample(Ray *ray, float3 light_P, floa
ccl_device float kernel_volume_equiangular_pdf(Ray *ray, float3 light_P, float sample_t)
{
float delta = dot((light_P - ray->P) , ray->D);
- float D = sqrtf(len_squared(light_P - ray->P) - delta * delta);
+ float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
+ if(UNLIKELY(D == 0.0f)) {
+ return 0.0f;
+ }
float t = ray->t;
float t_ = sample_t - delta;
float theta_a = -atan2f(delta, D);
float theta_b = atan2f(t - delta, D);
+ if(UNLIKELY(theta_b == theta_a)) {
+ return 0.0f;
+ }
float pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
@@ -958,6 +971,9 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
mis_weight = 2.0f*power_heuristic(pdf, distance_pdf);
}
}
+ if(sample_t < 1e-6f) {
+ return VOLUME_PATH_SCATTERED;
+ }
/* compute transmittance up to this step */
if(step != segment->steps)