manuel5975p 4 سال پیش
والد
کامیت
f7ba8110a7
3فایلهای تغییر یافته به همراه82 افزوده شده و 13 حذف شده
  1. 1 1
      CMakeLists.txt
  2. 78 10
      camera.cpp
  3. 3 2
      main.cpp

+ 1 - 1
CMakeLists.txt

@@ -7,7 +7,7 @@ endif()
 #set(CMAKE_CXX_STANDARD 20)
 set(CMAKE_EXPORT_COMPILE_COMMANDS True)
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -pthread -fopenmp")
-set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -Ofast -fopenmp -march=native -funroll-loops -std=c++20")
+set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -fopenmp -march=native -funroll-loops -std=c++20")
 FetchContent_Declare(
     objloader
     GIT_REPOSITORY https://github.com/manuel5975p/OBJ-Loader

+ 78 - 10
camera.cpp

@@ -1,6 +1,13 @@
 #include "camera.hpp"
 #include <Eigen/Dense>
 #include "warping.hpp"
+using namespace Eigen;
+struct hit{
+    Vector3f pos;
+    Vector3f normal;
+    Vector3f indir;
+    Vector3f outdir;
+};
 std::vector<Eigen::Vector3f> camera::get_image(const scene& sc, size_t n, sampler _rng)const{
     using namespace Eigen;
     std::vector<Eigen::Vector3f> img(n * n, Eigen::Vector3f(0,0,0));
@@ -19,7 +26,7 @@ std::vector<Eigen::Vector3f> camera::get_image(const scene& sc, size_t n, sample
             
             Eigen::Vector3d accum(0,0,0);
             
-            for(size_t smp = 0;smp < 4096;smp++){
+            for(size_t smp = 0;smp < 128;smp++){
                 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);
                 di.normalize();
                 struct RTCRayHit rayhit;
@@ -31,10 +38,12 @@ std::vector<Eigen::Vector3f> camera::get_image(const scene& sc, size_t n, sample
                 rayhit.ray.dir_z = di.z();
                 Vector3f hitpos = pos;
                 Vector3f transport(1,1,1);
-                for(size_t bounces = 0;bounces < 5;bounces++){
+                std::vector<hit> hits;
+                hits.reserve(6);
+                for(size_t bounces = 0;bounces < 6;bounces++){
                     struct RTCIntersectContext context;
                     rtcInitIntersectContext(&context);
-                    rayhit.ray.tnear = 0.00002f;
+                    rayhit.ray.tnear = 0.001f;
                     rayhit.ray.tfar = std::numeric_limits<float>::infinity();
                     rayhit.ray.mask = -1;
                     rayhit.ray.flags = 0;
@@ -44,35 +53,94 @@ std::vector<Eigen::Vector3f> camera::get_image(const scene& sc, size_t n, sample
                     raycasts++;
                     if(rayhit.hit.geomID != RTC_INVALID_GEOMETRY_ID){
                         if(sc.emitters.contains(rayhit.hit.geomID)){
-                            accum += (Eigen::Vector3d(0,1,1).array() * transport.cast<double>().array()).matrix();
-                            //std::cout << "sd" << std::endl;
+                            Eigen::Vector3d transport(0,1,1);
+                            for(auto it = hits.rbegin();it != hits.rend();it++){
+                                transport.array() *= it->outdir.dot(it->normal);
+                                for(const auto& pl : sc.pointlight){
+                                    struct RTCIntersectContext sh_context;
+                                    rtcInitIntersectContext(&sh_context);
+                                    Vector3f sh_ray(pl.pos - it->pos);
+                                    if(sh_ray.dot(it->normal) < 0)continue;
+                                    float sh_ray_length = sh_ray.norm();
+                                    sh_ray.normalize();
+                                    RTCRay rsh_ray;
+                                    rsh_ray.org_x = it->pos.x();
+                                    rsh_ray.org_y = it->pos.y();
+                                    rsh_ray.org_z = it->pos.z();
+                                    rsh_ray.dir_x = sh_ray.x();
+                                    rsh_ray.dir_y = sh_ray.y();
+                                    rsh_ray.dir_z = sh_ray.z();
+                                    rsh_ray.tnear = 0.001f;
+                                    rsh_ray.tfar = sh_ray_length;
+                                    rsh_ray.mask = -1;
+                                    rsh_ray.flags = 0;
+                                    raycasts++;
+                                    rtcOccluded1(sc.m_scene, &sh_context, &rsh_ray);
+                                    if(rsh_ray.tfar > 0){
+                                        transport += pl.color.cast<double>() * std::abs(sh_ray.dot(it->normal)) * (1.0 / double(sh_ray_length * sh_ray_length));
+                                    }
+                                }
+                            }
+                            accum += transport;
                             goto inner;
                         }
-                        //std::cout << std::to_string(rayhit.ray.tfar) + "\n";
                         rayhit.ray.org_x += rayhit.ray.dir_x * rayhit.ray.tfar;
                         rayhit.ray.org_y += rayhit.ray.dir_y * rayhit.ray.tfar;
                         rayhit.ray.org_z += rayhit.ray.dir_z * rayhit.ray.tfar;
                         Vector3f hitnormal = Vector3f(rayhit.hit.Ng_x, rayhit.hit.Ng_y, rayhit.hit.Ng_z).normalized();
-                        //std::cout << hitnormal << "\n\n";
-                        //Vector3f newdir = cosine_hemisphere(hitnormal, rng.next2D()).normalized();
+                        
                         Vector3f newdir = uniform_sphere(rng.next2D());
                         if(newdir.dot(hitnormal) <= 0){
                             newdir *= -1.0f;
                         }
+                        hits.push_back(hit{
+                            Vector3f(rayhit.ray.org_x, rayhit.ray.org_y, rayhit.ray.org_z),
+                            hitnormal,
+                            Vector3f(rayhit.ray.dir_x, rayhit.ray.dir_y, rayhit.ray.dir_z),
+                            newdir
+                        });
                         transport *= newdir.dot(hitnormal);
-                        //std::cout << std::to_string(newdir.dot(Vector3f(rayhit.hit.Ng_x, rayhit.hit.Ng_y, rayhit.hit.Ng_z).normalized())) + std::string("\n");
                         rayhit.ray.dir_x = newdir.x();
                         rayhit.ray.dir_y = newdir.y();
                         rayhit.ray.dir_z = newdir.z();
                     }
                     else{
+                        Eigen::Vector3d transport(0,0,0);
+                        for(auto it = hits.rbegin();it != hits.rend();it++){
+                            transport.array() *= it->outdir.dot(it->normal);
+                            for(const auto& pl : sc.pointlight){
+                                struct RTCIntersectContext sh_context;
+                                rtcInitIntersectContext(&sh_context);
+                                Vector3f sh_ray(pl.pos - it->pos);
+                                if(sh_ray.dot(it->normal) < 0)continue;
+                                float sh_ray_length = sh_ray.norm();
+                                sh_ray.normalize();
+                                RTCRay rsh_ray;
+                                rsh_ray.org_x = it->pos.x();
+                                rsh_ray.org_y = it->pos.y();
+                                rsh_ray.org_z = it->pos.z();
+                                rsh_ray.dir_x = sh_ray.x();
+                                rsh_ray.dir_y = sh_ray.y();
+                                rsh_ray.dir_z = sh_ray.z();
+                                rsh_ray.tnear = 0.001f;
+                                rsh_ray.tfar = sh_ray_length;
+                                rsh_ray.mask = -1;
+                                rsh_ray.flags = 0;
+                                raycasts++;
+                                rtcOccluded1(sc.m_scene, &sh_context, &rsh_ray);
+                                if(rsh_ray.tfar > 0){
+                                    transport += pl.color.cast<double>() * std::abs(sh_ray.dot(it->normal)) * 1 / (sh_ray_length * sh_ray_length);
+                                }
+                            }
+                        }
+                        accum += transport;
                         goto inner;
                     }
                 }
                 inner:
                 (void)0;
             }
-            img[j * n + i] = (accum.cast<float>() / 512.0f).array().pow(0.6f).matrix();
+            img[j * n + i] = (accum.cast<float>() / 32.0f).array().pow(0.5f).matrix();
         }
     }
     }

+ 3 - 2
main.cpp

@@ -44,9 +44,10 @@ int main(){
            0,0,0,1;
     scene.add_object(quad_mesh, trf, false);
 
-    scene.add_sphere(Vector3f(-1.5,0,0),0.5, true);
+    //scene.add_sphere(Vector3f(-1.5,0,0),0.5, true);
+    scene.pointlight.push_back(pointlight{Eigen::Vector3f(2,0,0), Eigen::Vector3f(1,1,0)});
     scene.build();
-    camera cam(Vector3f(0, 0.6 * 3, 2.4 * 3),Vector3f(0,0,0), Vector3f(0,1,0));
+    camera cam(Vector3f(0, 0.6, 2.4),Vector3f(0,0,0), Vector3f(0,1,0));
     sampler simp;
     size_t n = 2000;
     auto t1 = nanoTime();