warping.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #ifndef WARPING_HPP
  2. #define WARPING_HPP
  3. #include <Eigen/Dense>
  4. #include <cmath>
  5. #include <random>
  6. inline Eigen::Vector3f uniform_sphere(const Eigen::Vector2f& sample){
  7. using std::acos;
  8. using std::cos;
  9. using std::sin;
  10. std::uniform_real_distribution<float> dis(0, 1);
  11. float theta = 2 * M_PI * sample(0);
  12. float phi = acos(2 * sample(1) - 1);
  13. Eigen::Vector3f ret;
  14. ret(0) = sin(phi) * cos(theta);
  15. ret(1) = sin(phi) * sin(theta);
  16. ret(2) = cos(phi);
  17. return ret;
  18. }
  19. inline Eigen::Vector3f cosine_hemisphere(const Eigen::Vector3f& normal, const Eigen::Vector2f& sample) {
  20. using std::asin;
  21. using std::cos;
  22. using std::sin;
  23. using std::sqrt;
  24. //constexpr float r = 1;
  25. //float theta = asin(sqrt(sample.y()));
  26. //float phi = 2 * M_PI * sample.x();
  27. //float z = r * cos(theta);
  28. //float _r = sqrt(r * r - z * z);
  29. //float x = _r * cos(phi);
  30. //float y = _r * sin(phi);
  31. float r = sqrt(sample.x());
  32. float phi = 2 * M_PI * sample.y();
  33. float x = r * cos(phi);
  34. float y = r * sin(phi);
  35. float z = sqrt(1 - r * r);
  36. Eigen::Vector3f notnormal = normal;
  37. if(normal.y() == 0){
  38. std::swap(notnormal.x(), notnormal.z());
  39. notnormal.z() *= -1;
  40. }
  41. else{
  42. std::swap(notnormal.x(), notnormal.y());
  43. notnormal.y() *= -1;
  44. }
  45. Eigen::Vector3f notnormal2 = normal.cross(notnormal);
  46. notnormal = notnormal2.cross(normal);
  47. Eigen::Matrix3f trf;
  48. trf.col(0) = notnormal;
  49. trf.col(1) = notnormal2;
  50. trf.col(2) = normal;
  51. Eigen::Vector3f ret(x, y, z);
  52. return Eigen::Vector3f(trf * ret);
  53. }
  54. inline float beckmann_eval(const Eigen::Vector3f& m, float alpha) {
  55. using std::abs;
  56. using std::sqrt;
  57. using std::exp;
  58. using std::pow;
  59. if (m.z() > 0 && abs(m.squaredNorm() - 1) < 0.001f) {
  60. float costheta = m.z();
  61. float r = sqrt(m.x() * m.x() + m.y() * m.y());
  62. float tantheta = r / m.z();
  63. float upper = exp((-tantheta * tantheta) / (alpha * alpha));
  64. float lower = M_PI * alpha * alpha * pow(costheta, 3);
  65. return upper / lower;
  66. }
  67. return 0.0f;
  68. }
  69. inline Eigen::Vector3f beckmann(const Eigen::Vector2f& sample, float alpha) {
  70. using std::cos;
  71. using std::sin;
  72. using std::sqrt;
  73. using std::atan;
  74. using std::log;
  75. float theta = atan(sqrt(-alpha * alpha * log(1 - sample.y())));
  76. float pha = 2 * M_PI * sample.x();
  77. float z = cos(theta);
  78. float r = sqrt(1 - z * z);
  79. float y = r * cos(pha);
  80. float x = r * sin(pha);
  81. return Eigen::Vector3f(x, y, z);
  82. }
  83. #endif