diff --git a/Assignments/Assignment2/Application2.cpp b/Assignments/Assignment2/Application2.cpp index 3af9b01..431dd3e 100644 --- a/Assignments/Assignment2/Application2.cpp +++ b/Assignments/Assignment2/Application2.cpp @@ -1,6 +1,10 @@ #include "Application2.h" +#include "helper.hpp" +#include "random_sampler.hpp" #include +#define EPS 0.01f + void Application2::initScene() { Data_Constructor(&data, 1, 8); @@ -114,13 +118,160 @@ Vec3fa ACESFilm(Vec3fa x, float exposure) { Vec3fa Application2::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 renderPixelHomogeneous(x, y, camera, stats, sampler); } else { return Vec3fa(0.0f); } } Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) { - return Vec3fa(0.0f); + /* 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); + + float mu_t = mu_a + mu_s; + // float mu_t = 0.1; + float t; + if (mu_t == 0) { + t = inf; + } else { + // printf("%f\n", mu_t); + t = - std::log(1.0 - RandomSampler_get1D(sampler)) / mu_t; + } + + // if (t != t | t <= 0) { + // printf("t: %f;%f\n", t, ray.tfar); + // } + + if (t > 0.0 && t < ray.tfar) { + + // Nee + /* Light ray */ + return {0.0, 0.0, 0.0}; + int id = (int)(RandomSampler_get1D(sampler) * data.scene->lights.size()); + if (id == data.scene->lights.size()) + id = data.scene->lights.size() - 1; + const Light* l = data.scene->lights[id]; + Sample sample; + + Light_SampleRes ls = Lights_sample(l, sample, RandomSampler_get2D(sampler)); + + /* initialize shadow ray */ + Ray shadow(sample.P, ls.dir, EPS, ls.dist - EPS, 0.0f); + + + /* trace shadow ray */ + RTCOccludedArguments sargs; + rtcInitOccludedArguments(&sargs); + sargs.feature_mask = RTC_FEATURE_FLAG_TRIANGLE; + rtcOccluded1(data.g_scene, RTCRay_(shadow), &sargs); + RayStats_addShadowRay(stats); + + float scatter = phase(scattering_parameter, dot(ray.dir,shadow.dir)); + /* add light contribution if not occluded (NEE) */ + if (shadow.tfar >= 0.0f) { + // L += Lw * light_diffuse * ls.weight; + L += Lw * std::pow(M_E, - mu_t * shadow.tfar) * scatter * mu_s * ls.weight * dot(sample.Ng, ls.dir) / data.scene->lights.size(); + // L += Lw * light_diffuse * ls.weight/ data.scene->lights.size(); + } + + // new direction + + float pdf; + Vec3fa o = sample_phase_function(-ray.dir, scattering_parameter, RandomSampler_get2D(sampler), pdf); + + Lw *= std::pow(M_E, - mu_t * t) * mu_s; + + ray = Ray(ray.org + t * ray.dir,o,EPS,inf); + + } else if (ray.geomID != RTC_INVALID_GEOMETRY_ID) { + + 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)); + + // include direct light on first ray + if (lightID != unsigned(-1)) { + if (i == 0) { + // printf("lightID: %d\n", lightID); + 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); + + /* Light ray */ + int id = (int)(RandomSampler_get1D(sampler) * data.scene->lights.size()); + if (id == data.scene->lights.size()) + id = data.scene->lights.size() - 1; + // printf("id: %d\n", id); + const Light* l = data.scene->lights[id]; + + Light_SampleRes ls = Lights_sample(l, sample, RandomSampler_get2D(sampler)); + + Vec3fa light_diffuse = Material__eval(material_array, matId, brdf, wo, sample, ls.dir); + + /* initialize shadow ray */ + Ray shadow(sample.P, ls.dir, EPS, ls.dist - EPS, 0.0f); + + /* trace shadow ray */ + RTCOccludedArguments sargs; + rtcInitOccludedArguments(&sargs); + sargs.feature_mask = RTC_FEATURE_FLAG_TRIANGLE; + rtcOccluded1(data.g_scene, RTCRay_(shadow), &sargs); + RayStats_addShadowRay(stats); + + /* add light contribution if not occluded (NEE) */ + if (shadow.tfar >= 0.0f) { + // L += Lw * light_diffuse * ls.weight; + L += Lw * std::pow(M_E, - mu_t * shadow.tfar) *light_diffuse * ls.weight * dot(sample.Ng, ls.dir) / data.scene->lights.size(); + // L += Lw * light_diffuse * ls.weight/ data.scene->lights.size(); + } + + + // Use cosine sampling + 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); + // printf("pdf: %f\n", wi.pdf); + + Lw *= std::pow(M_E, - mu_t * ray.tfar) * diffuse / wi.pdf; + + ray = Ray(sample.P,wi.v,EPS,inf); + + } + } + + return L; } /* task that renders a single screen tile */ diff --git a/Assignments/Assignment2/Application2.h b/Assignments/Assignment2/Application2.h index 277940e..695c13b 100644 --- a/Assignments/Assignment2/Application2.h +++ b/Assignments/Assignment2/Application2.h @@ -1,5 +1,6 @@ #pragma once #include "helper.hpp" +#include "imgui.h" class Application2 : public Application { @@ -14,10 +15,18 @@ private: void drawGUI() override { ImGui::Checkbox("Bounding Box", &boundingBox); + ImGui::InputInt("Ray depth", &ray_depth); + if (ray_depth < 1) { + ray_depth = 1; + } const char* items[] = {"Original", "Homogeneous"}; ImGui::Combo("Version", &selected, items, 2); + ImGui::SliderFloat("mu_a", &mu_a, 0.0, 1.0); + ImGui::SliderFloat("mu_s", &mu_s, 0.0, 1.0); + ImGui::SliderFloat("scattering parameter", &scattering_parameter, 0.0, 1.0); + const char* scenes[] = {"Gnome", "Horse", "Heterogenous"}; int oldscene = scene; ImGui::Combo("Scenes", &scene, scenes, 3); @@ -43,7 +52,11 @@ private: void heterogenousScene(); + int ray_depth = 15; bool boundingBox = true; int selected = 0; int scene = 0; + float mu_a = 0.0; + float mu_s = 0.0; + float scattering_parameter = 0.4; };