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>2014-11-12 19:23:33 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2014-11-12 19:23:33 +0300
commit395ee33c8a5c806cdc8c4fe61df750b68f66d80d (patch)
tree4f08555af43c636061b04614e5fa9602959515de
parentf46e77fd561992b253c904a7c89a95d465d7feb0 (diff)
Cycles: Prevent NaN and inf in area lamp sampling caused by precision issues
This doesn't have noticeable affect on the render times, but avoids possible numerical issues.
-rw-r--r--intern/cycles/kernel/kernel_light.h26
1 files changed, 16 insertions, 10 deletions
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index f8d6d4117f8..9dfbfd91881 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -216,10 +216,10 @@ ccl_device float3 area_light_sample(float3 P,
float3 n2 = normalize(cross(v11, v01));
float3 n3 = normalize(cross(v01, v00));
/* Compute internal angles (gamma_i). */
- float g0 = acosf(-dot(n0, n1));
- float g1 = acosf(-dot(n1, n2));
- float g2 = acosf(-dot(n2, n3));
- float g3 = acosf(-dot(n3, n0));
+ float g0 = safe_acosf(-dot(n0, n1));
+ float g1 = safe_acosf(-dot(n1, n2));
+ float g2 = safe_acosf(-dot(n2, n3));
+ float g3 = safe_acosf(-dot(n3, n0));
/* Compute predefined constants. */
float b0 = n0.z;
float b1 = n2.z;
@@ -243,7 +243,10 @@ ccl_device float3 area_light_sample(float3 P,
float hv = h0 + randv * (h1 - h0), hv2 = hv * hv;
float yv = (hv2 < 1.0f - 1e-6f) ? (hv * d) / sqrtf(1.0f - hv2) : y1;
- *pdf = 1.0f / S;
+ if(S != 0.0f)
+ *pdf = 1.0f / S;
+ else
+ *pdf = 0.0f;
/* Transform (xu, yv, z0) to world coords. */
return P + xu * x + yv * y + z0 * z;
@@ -289,15 +292,18 @@ ccl_device float area_light_pdf(float3 P,
float3 n2 = normalize(cross(v11, v01));
float3 n3 = normalize(cross(v01, v00));
/* Compute internal angles (gamma_i). */
- float g0 = acosf(-dot(n0, n1));
- float g1 = acosf(-dot(n1, n2));
- float g2 = acosf(-dot(n2, n3));
- float g3 = acosf(-dot(n3, n0));
+ float g0 = safe_acosf(-dot(n0, n1));
+ float g1 = safe_acosf(-dot(n1, n2));
+ float g2 = safe_acosf(-dot(n2, n3));
+ float g3 = safe_acosf(-dot(n3, n0));
/* Compute predefined constants. */
float k = M_2PI_F - g2 - g3;
/* Compute solid angle from internal angles. */
float S = g0 + g1 - k;
- return 1.0f / S;
+ if(S != 0.0f)
+ return 1.0f / S;
+ else
+ return 0.0f;
}
ccl_device float spot_light_attenuation(float4 data1, float4 data2, LightSample *ls)