diff options
author | Lukas Stockner <lukas.stockner@freenet.de> | 2020-07-08 03:10:02 +0300 |
---|---|---|
committer | Lukas Stockner <lukas.stockner@freenet.de> | 2020-07-08 03:15:37 +0300 |
commit | 7fcb6bc59c85beab36dbfcec91d0cfaf5291f029 (patch) | |
tree | 0e7c93521d34efd2ba43ea8847dc2661effa34c3 /intern/cycles/util | |
parent | afcb41a0aaafce5b99891487a402d78a337f3809 (diff) |
Fix T78324: Different Sky Texture results between CPU and GPU
The problem here was numerical precision: The code calculates the angle between
sun and view direction, and the usual acos(dot(a, b)) approach for that has
poor numerical performance for almost parallel angles.
As a result, the generally tiny difference between floating point computation
between CPU and GPU was enough to make the sun vanish at different radii,
causing different results.
The new version fixes the difference by making the computation much more robust
on both platforms.
Diffstat (limited to 'intern/cycles/util')
-rw-r--r-- | intern/cycles/util/util_math.h | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 737c834e073..8caabf6eac3 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -787,6 +787,16 @@ ccl_device_inline float compare_floats(float a, float b, float abs_diff, int ulp return (abs(__float_as_int(a) - __float_as_int(b)) < ulp_diff); } +/* Calculate the angle between the two vectors a and b. + * The usual approach acos(dot(a, b)) has severe precision issues for small angles, + * which are avoided by this method. + * Based on "Mangled Angles" from https://people.eecs.berkeley.edu/~wkahan/Mindless.pdf + */ +ccl_device_inline float precise_angle(float3 a, float3 b) +{ + return 2.0f * atan2f(len(a - b), len(a + b)); +} + CCL_NAMESPACE_END #endif /* __UTIL_MATH_H__ */ |