Add Heterogeneous implementation.
This commit is contained in:
parent
f702e82b4f
commit
97dbc2db13
4 changed files with 145 additions and 20 deletions
|
|
@ -1,9 +1,13 @@
|
||||||
#include "Application2.h"
|
#include "Application2.h"
|
||||||
#include "embree4/rtcore_common.h"
|
#include "embree4/rtcore_common.h"
|
||||||
#include "helper.hpp"
|
#include "helper.hpp"
|
||||||
|
#include "lights/light.h"
|
||||||
|
#include "math/vec2.h"
|
||||||
|
#include "math/vec3fa.h"
|
||||||
#include "random_sampler.hpp"
|
#include "random_sampler.hpp"
|
||||||
#include "ray.hpp"
|
#include "ray.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
#define EPS 0.0001f
|
#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);
|
return renderPixelOrig(x, y, camera, stats, sampler);
|
||||||
} else if (selected == 1) {
|
} else if (selected == 1) {
|
||||||
return renderPixelHomogeneous(x, y, camera, stats, sampler);
|
return renderPixelHomogeneous(x, y, camera, stats, sampler);
|
||||||
|
} else if (selected == 2) {
|
||||||
|
return renderPixelHeterogeneous(x, y, camera, stats, sampler);
|
||||||
} else {
|
} else {
|
||||||
return Vec3fa(0.0f);
|
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 *> 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) {
|
Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) {
|
||||||
/* radiance accumulator and weight */
|
/* radiance accumulator and weight */
|
||||||
Vec3fa L = Vec3fa(0.0f);
|
Vec3fa L = Vec3fa(0.0f);
|
||||||
|
|
@ -162,16 +281,12 @@ Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera&
|
||||||
|
|
||||||
const Vec3fa wo = neg(ray.dir);
|
const Vec3fa wo = neg(ray.dir);
|
||||||
|
|
||||||
float mu_t = mu_a + mu_s;
|
|
||||||
if (!in_volume) {
|
|
||||||
mu_t = 0;
|
|
||||||
}
|
|
||||||
float t;
|
float t;
|
||||||
if (mu_t == 0) {
|
if (!in_volume | (density == 0)) {
|
||||||
t = inf;
|
t = inf;
|
||||||
} else {
|
} else {
|
||||||
// printf("%f\n", mu_t);
|
// printf("%f\n", density);
|
||||||
t = - std::log(1.0 - RandomSampler_get1D(sampler)) / mu_t;
|
t = - std::log(1.0 - RandomSampler_get1D(sampler)) / density;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (t != t | t <= 0) {
|
// 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.geomID == RTC_INVALID_GEOMETRY_ID) {
|
||||||
if (shadow_in_volume) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -237,7 +352,7 @@ Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera&
|
||||||
if (brdf.name == "default") {
|
if (brdf.name == "default") {
|
||||||
|
|
||||||
if (shadow_in_volume) {
|
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;
|
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) */
|
/* add light contribution if not occluded (NEE) */
|
||||||
if (Lwscatter > 0.0) {
|
if (Lwscatter > 0.0) {
|
||||||
// L += Lw * light_diffuse * ls.weight;
|
// 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();
|
// 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;
|
float pdf;
|
||||||
Vec3fa o = sample_phase_function(-ray.dir, scattering_parameter, RandomSampler_get2D(sampler), 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);
|
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.geomID == RTC_INVALID_GEOMETRY_ID) {
|
||||||
if (shadow_in_volume) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -358,7 +473,7 @@ Vec3fa Application2::renderPixelHomogeneous(float x, float y, const ISPCCamera&
|
||||||
if (brdf.name == "default") {
|
if (brdf.name == "default") {
|
||||||
|
|
||||||
if (shadow_in_volume) {
|
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;
|
shadow_in_volume = dot(normalize(shadow.Ng), shadow.dir) < 0;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ private:
|
||||||
Vec3fa renderPixel(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) override;
|
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 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 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 {
|
void drawGUI() override {
|
||||||
ImGui::Checkbox("Bounding Box", &boundingBox);
|
ImGui::Checkbox("Bounding Box", &boundingBox);
|
||||||
|
|
@ -23,19 +24,22 @@ private:
|
||||||
ray_depth = 1;
|
ray_depth = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* items[] = {"Original", "Homogeneous"};
|
const char* items[] = {"Original", "Homogeneous", "Heterogeneous"};
|
||||||
if (ImGui::Combo("Version", &selected, items, 2))
|
if (ImGui::Combo("Version", &selected, items, 3))
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
if (ImGui::SliderFloat("mu_a", &mu_a, 0.0, 1.0))
|
if (ImGui::SliderFloat("density", &density, 0.0, 1.0))
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
if (ImGui::SliderFloat("mu_s", &mu_s, 0.0, 1.0))
|
if (ImGui::SliderFloat("absorbtion", &absorbtion, 0.0, 1.0))
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
if (ImGui::SliderFloat("scattering parameter", &scattering_parameter, -1.0, 1.0))
|
if (ImGui::SliderFloat("scattering parameter", &scattering_parameter, -1.0, 1.0))
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
|
if (ImGui::SliderFloat("temperature", &tempearture_multiplier, 1.0, 10000.0))
|
||||||
|
clear();
|
||||||
|
|
||||||
const char* scenes[] = {"Gnome", "Horse", "Heterogenous"};
|
const char* scenes[] = {"Gnome", "Horse", "Heterogenous"};
|
||||||
if (ImGui::Combo("Scenes", &scene, scenes, 3)) {
|
if (ImGui::Combo("Scenes", &scene, scenes, 3)) {
|
||||||
Data_Destructor(&data);
|
Data_Destructor(&data);
|
||||||
|
|
@ -70,7 +74,8 @@ private:
|
||||||
bool boundingBox = true;
|
bool boundingBox = true;
|
||||||
int selected = 0;
|
int selected = 0;
|
||||||
int scene = 0;
|
int scene = 0;
|
||||||
float mu_a = 0.0;
|
float density = 0.0;
|
||||||
float mu_s = 0.0;
|
float absorbtion = 0.0;
|
||||||
|
float tempearture_multiplier = 1000.0;
|
||||||
float scattering_parameter = 0.4;
|
float scattering_parameter = 0.4;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ protected:
|
||||||
double clickX = 0;
|
double clickX = 0;
|
||||||
double clickY = 0;
|
double clickY = 0;
|
||||||
|
|
||||||
float speed = 10;
|
float speed = 400;
|
||||||
Vec3f moveDelta = {0, 0, 0};
|
Vec3f moveDelta = {0, 0, 0};
|
||||||
|
|
||||||
RayStats* g_stats = nullptr;
|
RayStats* g_stats = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,11 @@ namespace embree
|
||||||
|
|
||||||
data.resize(res.x * res.y * res.z);
|
data.resize(res.x * res.y * res.z);
|
||||||
file.read(reinterpret_cast<char*>(data.data()), data.size() * sizeof(float));
|
file.read(reinterpret_cast<char*>(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();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue