fastApproximateAtan.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. //This file is automatically rebuilt by the Cesium build process.
  2. export default "/**\n\
  3. * Approxiamtes atan over the range [0, 1]. Safe to flip output for negative input.\n\
  4. *\n\
  5. * Based on Michal Drobot's approximation from ShaderFastLibs, which in turn is based on\n\
  6. * \"Efficient approximations for the arctangent function,\" Rajan, S. Sichun Wang Inkol, R. Joyal, A., May 2006.\n\
  7. * Adapted from ShaderFastLibs under MIT License.\n\
  8. *\n\
  9. * Chosen for the following characteristics over range [0, 1]:\n\
  10. * - basically no error at 0 and 1, important for getting around range limit (naive atan2 via atan requires infinite range atan)\n\
  11. * - no visible artifacts from first-derivative discontinuities, unlike latitude via range-reduced sqrt asin approximations (at equator)\n\
  12. *\n\
  13. * The original code is x * (-0.1784 * abs(x) - 0.0663 * x * x + 1.0301);\n\
  14. * Removed the abs() in here because it isn't needed, the input range is guaranteed as [0, 1] by how we're approximating atan2.\n\
  15. *\n\
  16. * @name czm_fastApproximateAtan\n\
  17. * @glslFunction\n\
  18. *\n\
  19. * @param {float} x Value between 0 and 1 inclusive.\n\
  20. *\n\
  21. * @returns {float} Approximation of atan(x)\n\
  22. */\n\
  23. float czm_fastApproximateAtan(float x) {\n\
  24. return x * (-0.1784 * x - 0.0663 * x * x + 1.0301);\n\
  25. }\n\
  26. \n\
  27. /**\n\
  28. * Approximation of atan2.\n\
  29. *\n\
  30. * Range reduction math based on nvidia's cg reference implementation for atan2: http://developer.download.nvidia.com/cg/atan2.html\n\
  31. * However, we replaced their atan curve with Michael Drobot's (see above).\n\
  32. *\n\
  33. * @name czm_fastApproximateAtan\n\
  34. * @glslFunction\n\
  35. *\n\
  36. * @param {float} x Value between -1 and 1 inclusive.\n\
  37. * @param {float} y Value between -1 and 1 inclusive.\n\
  38. *\n\
  39. * @returns {float} Approximation of atan2(x, y)\n\
  40. */\n\
  41. float czm_fastApproximateAtan(float x, float y) {\n\
  42. // atan approximations are usually only reliable over [-1, 1], or, in our case, [0, 1] due to modifications.\n\
  43. // So range-reduce using abs and by flipping whether x or y is on top.\n\
  44. float t = abs(x); // t used as swap and atan result.\n\
  45. float opposite = abs(y);\n\
  46. float adjacent = max(t, opposite);\n\
  47. opposite = min(t, opposite);\n\
  48. \n\
  49. t = czm_fastApproximateAtan(opposite / adjacent);\n\
  50. \n\
  51. // Undo range reduction\n\
  52. t = czm_branchFreeTernary(abs(y) > abs(x), czm_piOverTwo - t, t);\n\
  53. t = czm_branchFreeTernary(x < 0.0, czm_pi - t, t);\n\
  54. t = czm_branchFreeTernary(y < 0.0, -t, t);\n\
  55. return t;\n\
  56. }\n\
  57. ";