diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2016-08-09 13:20:08 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2016-08-09 13:20:22 +0300 |
commit | a7f6f900f373bda23d90e86a407e0d36fbdd8a03 (patch) | |
tree | 97b861102ff94f85d56584ecef2be1fbe820c154 | |
parent | c2a7317d1f4971bba0652bb56aadb01ff11702d9 (diff) |
Cycles: avoid making NaNs in Vector Math node by normalizing zero vectors.
Since inputs are user controlled, the node can't assume they aren't zero.
-rw-r--r-- | intern/cycles/kernel/svm/svm_math_util.h | 10 | ||||
-rw-r--r-- | intern/cycles/util/util_math.h | 6 |
2 files changed, 9 insertions, 7 deletions
diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h index 3f7d18a02fe..6d13a0d8e02 100644 --- a/intern/cycles/kernel/svm/svm_math_util.h +++ b/intern/cycles/kernel/svm/svm_math_util.h @@ -32,21 +32,17 @@ ccl_device void svm_vector_math(float *Fac, float3 *Vector, NodeVectorMath type, *Fac = average_fac(*Vector); } else if(type == NODE_VECTOR_MATH_AVERAGE) { - *Fac = len(Vector1 + Vector2); - *Vector = normalize(Vector1 + Vector2); + *Vector = safe_normalize_len(Vector1 + Vector2, Fac); } else if(type == NODE_VECTOR_MATH_DOT_PRODUCT) { *Fac = dot(Vector1, Vector2); *Vector = make_float3(0.0f, 0.0f, 0.0f); } else if(type == NODE_VECTOR_MATH_CROSS_PRODUCT) { - float3 c = cross(Vector1, Vector2); - *Fac = len(c); - *Vector = normalize(c); + *Vector = safe_normalize_len(cross(Vector1, Vector2), Fac); } else if(type == NODE_VECTOR_MATH_NORMALIZE) { - *Fac = len(Vector1); - *Vector = normalize(Vector1); + *Vector = safe_normalize_len(Vector1, Fac); } else { *Fac = 0.0f; diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 13aba0646d2..89a882d9b9d 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -572,6 +572,12 @@ ccl_device_inline float3 safe_normalize(const float3 a) return (t != 0.0f)? a/t: a; } +ccl_device_inline float3 safe_normalize_len(const float3 a, float *t) +{ + *t = len(a); + return (*t != 0.0f)? a/(*t): a; +} + #ifndef __KERNEL_OPENCL__ ccl_device_inline bool operator==(const float3 a, const float3 b) |