From 97dbc2db134083c5756ce08aeb9b5a51694b5c7c Mon Sep 17 00:00:00 2001 From: hal8174 Date: Wed, 5 Jun 2024 16:58:06 +0200 Subject: [PATCH] Add Heterogeneous implementation. --- Assignments/Assignment2/Application2.cpp | 141 ++++++++++++++++++++--- Assignments/Assignment2/Application2.h | 17 ++- Framework/include/application.h | 2 +- Framework/scenegraph/grid.h | 5 + 4 files changed, 145 insertions(+), 20 deletions(-) diff --git a/Assignments/Assignment2/Application2.cpp b/Assignments/Assignment2/Application2.cpp index bfa5529..1c6e30f 100644 --- a/Assignments/Assignment2/Application2.cpp +++ b/Assignments/Assignment2/Application2.cpp @@ -1,9 +1,13 @@ #include "Application2.h" #include "embree4/rtcore_common.h" #include "helper.hpp" +#include "lights/light.h" +#include "math/vec2.h" +#include "math/vec3fa.h" #include "random_sampler.hpp" #include "ray.hpp" #include +#include #define EPS 0.0001f @@ -135,11 +139,126 @@ Vec3fa Application2::renderPixel(float x, float y, const ISPCCamera& camera, Ray return renderPixelOrig(x, y, camera, stats, sampler); } else if (selected == 1) { return renderPixelHomogeneous(x, y, camera, stats, sampler); + } else if (selected == 2) { + return renderPixelHeterogeneous(x, y, camera, stats, sampler); } else { return Vec3fa(0.0f); } } +Vec3fa Application2::renderPixelHeterogeneous(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) { + + Vec3fa L = Vec3fa(0.0f); + Vec3fa Lw = Vec3fa(1.0f); + + bool in_volume = false; + float max_density = 1.32 * density; // tested + + /* 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 t; + if (!in_volume | (density == 0)) { + t = inf; + } else { + // printf("%f\n", density); + t = - std::log(1.0 - RandomSampler_get1D(sampler)) / max_density; + } + + if (t > 0.0 && t < ray.tfar) { + + if (ray.geomID == RTC_INVALID_GEOMETRY_ID) { + break; + } + + float r = RandomSampler_get1D(sampler); + Vec3fa p = ray.org + t * ray.dir; + // printf("%f\t%f\t(%f,%f,%f)\n", t, ray.tfar, p.x, p.y, p.z); + float s = data.densityGrid->sampleW(p); + // if (s != -1.0) { + // printf("(%f,%f,%f)\tt: %f\ttfar: %f\tr: %f\t%f\ts: %f\t%f\tp:%f\n",p.x, p.y, p.z, t, ray.tfar, r, r * max_density, s, s * density, (s * density) / max_density); + // } + // if (s > 0.5) { + // printf("(%f,%f,%f)\tr: %f\t%f\ts: %f\t%f\tp:%f\n",p.x, p.y, p.z , r, r * max_density, s, s * density, (s * density) / max_density); + // } + + if (RandomSampler_get1D(sampler) * max_density < s * density) { + + + float pdf; + Vec3fa o = sample_phase_function(-ray.dir, scattering_parameter, RandomSampler_get2D(sampler), pdf); + + float temp = data.tempGrid->sampleW(p); // Sample density from the grid + // float temp = 20; + float redWavelength = 700; + float greenWavelength = 530; + float blueWavelength = 470; + Vec3fa emissive = Vec3fa(0.0, 0.0, 0.0); + if (temp != -1.0f && temp > 0.001) { + temp *= tempearture_multiplier; + emissive = Vec3f(blackbody_radiance_normalized(redWavelength, temp), + blackbody_radiance_normalized(greenWavelength, temp), + blackbody_radiance_normalized(blueWavelength, temp)); + } + L += Lw * absorbtion * emissive; + Lw *= 1.0 - absorbtion; + + ray = Ray(ray.org + t * ray.dir,o,EPS,inf); + + } else { + // printf("volume(%f,%f,%f), t: %f, tfar: %f\n", ray.org.x, ray.org.y, ray.org.z, t, ray.tfar); + ray = Ray(ray.org + t * ray.dir, ray.dir, EPS, inf); + i--; + } + + } else if (ray.geomID != RTC_INVALID_GEOMETRY_ID) { + + Sample sample = createSample(ray); + int matId = data.scene->geometries.at(ray.geomID)->materialID; + unsigned lightID = data.scene->geometries.at(ray.geomID)->lightID; + + 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); + if (brdf.name == "default") { + // printf("surface\n"); + + in_volume = !in_volume; + // in_volume = dot(normalize(ray.Ng), ray.dir) < 0; + + ray = Ray(ray.org + ray.tfar * ray.dir, ray.dir, EPS, inf); + + i--; + + } + } + + } + + return L; +} + Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) { /* radiance accumulator and weight */ Vec3fa L = Vec3fa(0.0f); @@ -162,16 +281,12 @@ Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera& const Vec3fa wo = neg(ray.dir); - float mu_t = mu_a + mu_s; - if (!in_volume) { - mu_t = 0; - } float t; - if (mu_t == 0) { + if (!in_volume | (density == 0)) { t = inf; } else { - // printf("%f\n", mu_t); - t = - std::log(1.0 - RandomSampler_get1D(sampler)) / mu_t; + // printf("%f\n", density); + t = - std::log(1.0 - RandomSampler_get1D(sampler)) / density; } // if (t != t | t <= 0) { @@ -222,7 +337,7 @@ Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera& if (shadow.geomID == RTC_INVALID_GEOMETRY_ID) { if (shadow_in_volume) { - Lwscatter *= std::pow(M_E, - mu_t * (shadow.tfar - shadow.tnear())); + Lwscatter *= std::pow(M_E, - density * (shadow.tfar - shadow.tnear())); } break; } @@ -237,7 +352,7 @@ Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera& if (brdf.name == "default") { if (shadow_in_volume) { - Lwscatter *= std::pow(M_E, - mu_t * (shadow.tfar - shadow.tnear())); + Lwscatter *= std::pow(M_E, - density * (shadow.tfar - shadow.tnear())); } shadow_in_volume = dot(normalize(shadow.Ng), shadow.dir) < 0; @@ -262,7 +377,7 @@ Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera& /* add light contribution if not occluded (NEE) */ if (Lwscatter > 0.0) { // L += Lw * light_diffuse * ls.weight; - L += Lw * Lwscatter * scatter * (mu_s / mu_t) * ls.weight * dot(sample.Ng, ls.dir) / data.scene->lights.size(); + L += Lw * Lwscatter * scatter * (1.0 - absorbtion) * ls.weight * dot(sample.Ng, ls.dir) / data.scene->lights.size(); // L += Lw * light_diffuse * ls.weight/ data.scene->lights.size(); } @@ -271,7 +386,7 @@ Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera& float pdf; Vec3fa o = sample_phase_function(-ray.dir, scattering_parameter, RandomSampler_get2D(sampler), pdf); - Lw *= mu_s / mu_t; + Lw *= 1.0 - absorbtion; ray = Ray(ray.org + t * ray.dir,o,EPS,inf); @@ -343,7 +458,7 @@ Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera& if (shadow.geomID == RTC_INVALID_GEOMETRY_ID) { if (shadow_in_volume) { - Lwscatter *= std::pow(M_E, - mu_t * (shadow.tfar - shadow.tnear())); + Lwscatter *= std::pow(M_E, - density * (shadow.tfar - shadow.tnear())); } break; } @@ -358,7 +473,7 @@ Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera& if (brdf.name == "default") { if (shadow_in_volume) { - Lwscatter *= std::pow(M_E, - mu_t * (shadow.tfar - shadow.tnear())); + Lwscatter *= std::pow(M_E, - density * (shadow.tfar - shadow.tnear())); } shadow_in_volume = dot(normalize(shadow.Ng), shadow.dir) < 0; diff --git a/Assignments/Assignment2/Application2.h b/Assignments/Assignment2/Application2.h index cc37c10..85d5c4f 100644 --- a/Assignments/Assignment2/Application2.h +++ b/Assignments/Assignment2/Application2.h @@ -13,6 +13,7 @@ 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 renderPixelHomogeneous(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler); + Vec3fa renderPixelHeterogeneous(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler); void drawGUI() override { ImGui::Checkbox("Bounding Box", &boundingBox); @@ -23,19 +24,22 @@ private: ray_depth = 1; } - const char* items[] = {"Original", "Homogeneous"}; - if (ImGui::Combo("Version", &selected, items, 2)) + const char* items[] = {"Original", "Homogeneous", "Heterogeneous"}; + if (ImGui::Combo("Version", &selected, items, 3)) clear(); - if (ImGui::SliderFloat("mu_a", &mu_a, 0.0, 1.0)) + if (ImGui::SliderFloat("density", &density, 0.0, 1.0)) clear(); - if (ImGui::SliderFloat("mu_s", &mu_s, 0.0, 1.0)) + if (ImGui::SliderFloat("absorbtion", &absorbtion, 0.0, 1.0)) clear(); if (ImGui::SliderFloat("scattering parameter", &scattering_parameter, -1.0, 1.0)) clear(); + if (ImGui::SliderFloat("temperature", &tempearture_multiplier, 1.0, 10000.0)) + clear(); + const char* scenes[] = {"Gnome", "Horse", "Heterogenous"}; if (ImGui::Combo("Scenes", &scene, scenes, 3)) { Data_Destructor(&data); @@ -70,7 +74,8 @@ private: bool boundingBox = true; int selected = 0; int scene = 0; - float mu_a = 0.0; - float mu_s = 0.0; + float density = 0.0; + float absorbtion = 0.0; + float tempearture_multiplier = 1000.0; float scattering_parameter = 0.4; }; diff --git a/Framework/include/application.h b/Framework/include/application.h index 713af4c..e4bf2ba 100644 --- a/Framework/include/application.h +++ b/Framework/include/application.h @@ -130,7 +130,7 @@ protected: double clickX = 0; double clickY = 0; - float speed = 10; + float speed = 400; Vec3f moveDelta = {0, 0, 0}; RayStats* g_stats = nullptr; diff --git a/Framework/scenegraph/grid.h b/Framework/scenegraph/grid.h index 6ed233e..015b4ed 100644 --- a/Framework/scenegraph/grid.h +++ b/Framework/scenegraph/grid.h @@ -54,6 +54,11 @@ namespace embree data.resize(res.x * res.y * res.z); file.read(reinterpret_cast(data.data()), data.size() * sizeof(float)); + float max = 0; + for (size_t i = 0; i < res.x * res.y * res.z; i++) { + max = std::max(data[i], max); + } + printf("max:\t%f\n", max); file.close(); }