camera.cpp 4.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #include "camera.hpp"
  2. #include <Eigen/Dense>
  3. #include "warping.hpp"
  4. std::vector<Eigen::Vector3f> camera::get_image(const scene& sc, size_t n, sampler _rng)const{
  5. using namespace Eigen;
  6. std::vector<Eigen::Vector3f> img(n * n, Eigen::Vector3f(0,0,0));
  7. const Eigen::Vector3f lookray = (look_at - pos).normalized();
  8. const Eigen::Vector3f left = lookray.cross(up).normalized();
  9. const Eigen::Vector3f realup = left.cross(lookray);
  10. const int n2 = n / 2;
  11. size_t raycasts = 0;
  12. #pragma omp parallel
  13. {
  14. sampler rng;
  15. std::uniform_real_distribution<float> pert_dis(-0.5,0.5);
  16. #pragma omp for collapse(2) schedule(guided) reduction(+:raycasts)
  17. for(int j = 0;j < n;j++){
  18. for(int i = 0;i < n;i++){
  19. Eigen::Vector3d accum(0,0,0);
  20. for(size_t smp = 0;smp < 4096;smp++){
  21. Eigen::Vector3f di = lookray + (left * ((pert_dis(rng.m_rng) + float(i - n2)) / n2 / 1.5)) + realup * ((pert_dis(rng.m_rng) + float(j - n2)) / n2 / 1.5);
  22. di.normalize();
  23. struct RTCRayHit rayhit;
  24. rayhit.ray.org_x = pos.x();
  25. rayhit.ray.org_y = pos.y();
  26. rayhit.ray.org_z = pos.z();
  27. rayhit.ray.dir_x = di.x();
  28. rayhit.ray.dir_y = di.y();
  29. rayhit.ray.dir_z = di.z();
  30. Vector3f hitpos = pos;
  31. Vector3f transport(1,1,1);
  32. for(size_t bounces = 0;bounces < 5;bounces++){
  33. struct RTCIntersectContext context;
  34. rtcInitIntersectContext(&context);
  35. rayhit.ray.tnear = 0.00002f;
  36. rayhit.ray.tfar = std::numeric_limits<float>::infinity();
  37. rayhit.ray.mask = -1;
  38. rayhit.ray.flags = 0;
  39. rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
  40. rayhit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID;
  41. rtcIntersect1(sc.m_scene, &context, &rayhit);
  42. raycasts++;
  43. if(rayhit.hit.geomID != RTC_INVALID_GEOMETRY_ID){
  44. if(sc.emitters.contains(rayhit.hit.geomID)){
  45. accum += (Eigen::Vector3d(0,1,1).array() * transport.cast<double>().array()).matrix();
  46. //std::cout << "sd" << std::endl;
  47. goto inner;
  48. }
  49. //std::cout << std::to_string(rayhit.ray.tfar) + "\n";
  50. rayhit.ray.org_x += rayhit.ray.dir_x * rayhit.ray.tfar;
  51. rayhit.ray.org_y += rayhit.ray.dir_y * rayhit.ray.tfar;
  52. rayhit.ray.org_z += rayhit.ray.dir_z * rayhit.ray.tfar;
  53. Vector3f hitnormal = Vector3f(rayhit.hit.Ng_x, rayhit.hit.Ng_y, rayhit.hit.Ng_z).normalized();
  54. //std::cout << hitnormal << "\n\n";
  55. //Vector3f newdir = cosine_hemisphere(hitnormal, rng.next2D()).normalized();
  56. Vector3f newdir = uniform_sphere(rng.next2D());
  57. if(newdir.dot(hitnormal) <= 0){
  58. newdir *= -1.0f;
  59. }
  60. transport *= newdir.dot(hitnormal);
  61. //std::cout << std::to_string(newdir.dot(Vector3f(rayhit.hit.Ng_x, rayhit.hit.Ng_y, rayhit.hit.Ng_z).normalized())) + std::string("\n");
  62. rayhit.ray.dir_x = newdir.x();
  63. rayhit.ray.dir_y = newdir.y();
  64. rayhit.ray.dir_z = newdir.z();
  65. }
  66. else{
  67. goto inner;
  68. }
  69. }
  70. inner:
  71. (void)0;
  72. }
  73. img[j * n + i] = (accum.cast<float>() / 512.0f).array().pow(0.6f).matrix();
  74. }
  75. }
  76. }
  77. std::cout << std::to_string(raycasts) + " Raycasts\n";
  78. return img;
  79. }
  80. camera::camera(const Eigen::Vector3f& loc, const Eigen::Vector3f& look, const Eigen::Vector3f& u) : pos(loc), look_at(look), up(u){
  81. }