From 0b132ea4e738a25207c15edd2e8bdd8f54888eb7 Mon Sep 17 00:00:00 2001 From: hal8174 Date: Thu, 2 May 2024 12:37:21 +0200 Subject: [PATCH] Add path tracing implementation for Assignment1. --- Assignments/Assignment1/Application1.cpp | 86 +++++++++++++++++++++++- Assignments/Assignment1/Application1.h | 28 ++++++++ 2 files changed, 111 insertions(+), 3 deletions(-) diff --git a/Assignments/Assignment1/Application1.cpp b/Assignments/Assignment1/Application1.cpp index cda3722..113b053 100644 --- a/Assignments/Assignment1/Application1.cpp +++ b/Assignments/Assignment1/Application1.cpp @@ -1,4 +1,10 @@ #include "Application1.h" +#include "helper.hpp" +#include "lights/light.h" +#include "math/vec3fa.h" +#include "random_sampler.hpp" +#include "ray.hpp" +#include "sampling.hpp" void Application1::initScene() { Data_Constructor(&data, 1, 8); @@ -62,8 +68,82 @@ void Application1::veachScene() { scene = nullptr; } -/* task that renders a single screen tile */ Vec3fa Application1::renderPixel(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) { + if (selected == 0) { + return renderPixelOrig(x, y, camera, stats, sampler); + } else if (selected == 1) { + return renderPixelPathTracer(x, y, camera, stats, sampler); + } else { + return Vec3fa(0.0f); + } +} + +Vec3fa Application1::renderPixelPathTracer(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) { + /* radiance accumulator and weight */ + Vec3fa L = Vec3fa(0.0f); + Vec3fa Lw = Vec3fa(1.0f); + + /* initialize ray */ + Ray ray(Vec3fa(camera.xfm.p), Vec3fa(normalize(x * camera.xfm.l.vx + y * camera.xfm.l.vy + camera.xfm.l.vz)), 0.0f, + inf); + + + for (int i = 0; i < ray_depth; i++) { + /* intersect ray with scene */ + RTCIntersectArguments iargs; + rtcInitIntersectArguments(&iargs); + iargs.feature_mask = RTC_FEATURE_FLAG_TRIANGLE; + rtcIntersect1(data.g_scene, RTCRayHit_(ray), &iargs); + RayStats_addRay(stats); + + const Vec3fa wo = neg(ray.dir); + + /* shade pixels */ + if (ray.geomID == RTC_INVALID_GEOMETRY_ID) { + break; + } + + + Vec3fa Ns = normalize(ray.Ng); + Sample sample; + sample.P = ray.org + ray.tfar * ray.dir; + sample.Ng = ray.Ng; + sample.Ns = Ns; + int matId = data.scene->geometries[ray.geomID]->materialID; + unsigned lightID = data.scene->geometries[ray.geomID]->lightID; + sample.Ng = face_forward(ray.dir, normalize(sample.Ng)); + sample.Ns = face_forward(ray.dir, normalize(sample.Ns)); + + if (lightID != unsigned(-1)) { + const Light* l = data.scene->lights[lightID]; + Light_EvalRes evalRes = Lights_eval(l, sample, -wo); + L += Lw * evalRes.value; + break; + } + + /* calculate BRDF */ + BRDF brdf; + std::vector material_array = data.scene->materials; + Material__preprocess(material_array, matId, brdf, wo, sample); + + /* sample BRDF at hit point */ + + Vec2f uv = RandomSampler_get2D(sampler); + Sample3f wi = cosineSampleHemisphere(uv.x, uv.y, sample.Ng); + + Vec3fa diffuse = Material__eval(material_array, matId, brdf, wo, sample, wi.v); + + Lw *= M_PI * diffuse; + + ray = Ray(sample.P,wi.v,0.1,inf); + + } + + return L; +} + +/* task that renders a single screen tile */ +Vec3fa Application1::renderPixelOrig(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) { /* radiance accumulator and weight */ Vec3fa L = Vec3fa(0.0f); Vec3fa Lw = Vec3fa(1.0f); @@ -106,8 +186,8 @@ Vec3fa Application1::renderPixel(float x, float y, const ISPCCamera& camera, Ray Material__preprocess(material_array, matId, brdf, wo, sample); /* sample BRDF at hit point */ - Sample3f wi1; - Material__sample(material_array, matId, brdf, Lw, wo, sample, wi1, RandomSampler_get2D(sampler)); + // Sample3f wi1; + // Material__sample(material_array, matId, brdf, Lw, wo, sample, wi1, RandomSampler_get2D(sampler)); int id = (int)(RandomSampler_get1D(sampler) * data.scene->lights.size()); if (id == data.scene->lights.size()) diff --git a/Assignments/Assignment1/Application1.h b/Assignments/Assignment1/Application1.h index 32e8ec3..eddaa5e 100644 --- a/Assignments/Assignment1/Application1.h +++ b/Assignments/Assignment1/Application1.h @@ -1,5 +1,6 @@ #pragma once #include "helper.hpp" +#include "imgui.h" class Application1 : public Application { @@ -9,8 +10,31 @@ public: private: Vec3fa renderPixel(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) override; + Vec3fa renderPixelOrig(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler); + Vec3fa renderPixelPathTracer(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler); void drawGUI() override { + ImGui::ColorEdit3("Color", colorLight); + ImGui::InputInt("Ray depth", &ray_depth); + if (ray_depth < 1) { + ray_depth = 1; + } + + const char* items[] = {"Original", "Path Tracer"}; + ImGui::Combo("Version", &selected, items, 2); + + const char* scenes[] = {"Cornell", "Veach"}; + int oldscene = scene; + ImGui::Combo("Scenes", &scene, scenes, 2); + if (scene != oldscene) { + Data_Destructor(&data); + Data_Constructor(&data, 1, 8); + if (scene == 0) + standardScene(); + if (scene == 1) + veachScene(); + } + } void initScene() override; @@ -20,4 +44,8 @@ private: void veachScene(); float colorLight[3] = {1.0f, 1.0f, 1.0f}; + int ray_depth = 5; + int selected = 0; + int scene = 0; + };