Compare commits

...

3 commits

Author SHA1 Message Date
c48475ca52 Use material sampling. 2024-05-06 12:13:21 +02:00
616741d7dd Implement Next Event Estimation. 2024-05-06 12:02:55 +02:00
30e0019a88 Fix Framework error. 2024-05-06 12:02:35 +02:00
3 changed files with 107 additions and 9 deletions

View file

@ -6,6 +6,8 @@
#include "ray.hpp" #include "ray.hpp"
#include "sampling.hpp" #include "sampling.hpp"
#define EPS 0.1f
void Application1::initScene() { void Application1::initScene() {
Data_Constructor(&data, 1, 8); Data_Constructor(&data, 1, 8);
@ -70,14 +72,109 @@ void Application1::veachScene() {
Vec3fa Application1::renderPixel(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) { Vec3fa Application1::renderPixel(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) {
if (selected == 0) { if (selected == 0) {
return renderPixelOrig(x, y, camera, stats, sampler); return renderPixelOrig(x, y, camera, stats, sampler);
} else if (selected == 1) { } else if (selected == 1) {
return renderPixelPathTracer(x, y, camera, stats, sampler); return renderPixelPathTracer(x, y, camera, stats, sampler);
} else if (selected == 2) {
return renderPixelNextEventEstimation(x, y, camera, stats, sampler);
} else { } else {
return Vec3fa(0.0f); return Vec3fa(0.0f);
} }
} }
Vec3fa Application1::renderPixelNextEventEstimation(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)) {
if (i == 0) {
const Light* l = data.scene->lights[lightID];
Light_EvalRes evalRes = Lights_eval(l, sample, -wo);
L += Lw * evalRes.value * dot(sample.Ng, -ray.dir);
}
break;
}
/* calculate BRDF */
BRDF brdf;
std::vector<Material *> 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;
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 */
if (shadow.tfar >= 0.0f) {
// L += Lw * light_diffuse * ls.weight;
L += Lw * light_diffuse * ls.weight * dot(sample.Ng, ls.dir) / data.scene->lights.size();
}
/* sample BRDF at hit point */
Vec2f uv = RandomSampler_get2D(sampler);
Sample3f wi;
Vec3fa diffuse = Material__sample(material_array, matId, brdf, Lw, wo, sample, wi, uv);
Lw *= M_PI * diffuse;
ray = Ray(sample.P,wi.v, EPS,inf);
}
return L;
}
Vec3fa Application1::renderPixelPathTracer(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler) { Vec3fa Application1::renderPixelPathTracer(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);
@ -117,7 +214,7 @@ Vec3fa Application1::renderPixelPathTracer(float x, float y, const ISPCCamera& c
if (lightID != unsigned(-1)) { if (lightID != unsigned(-1)) {
const Light* l = data.scene->lights[lightID]; const Light* l = data.scene->lights[lightID];
Light_EvalRes evalRes = Lights_eval(l, sample, -wo); Light_EvalRes evalRes = Lights_eval(l, sample, -wo);
L += Lw * evalRes.value; return Lw * evalRes.value * dot(wo, sample.Ng);
break; break;
} }
@ -129,13 +226,13 @@ Vec3fa Application1::renderPixelPathTracer(float x, float y, const ISPCCamera& c
/* sample BRDF at hit point */ /* sample BRDF at hit point */
Vec2f uv = RandomSampler_get2D(sampler); Vec2f uv = RandomSampler_get2D(sampler);
Sample3f wi = cosineSampleHemisphere(uv.x, uv.y, sample.Ng); Sample3f wi;
Vec3fa diffuse = Material__eval(material_array, matId, brdf, wo, sample, wi.v); Vec3fa diffuse = Material__sample(material_array, matId, brdf, Lw, wo, sample, wi, uv);
Lw *= M_PI * diffuse; Lw *= M_PI * diffuse;
ray = Ray(sample.P,wi.v,0.1,inf); ray = Ray(sample.P,wi.v,EPS,inf);
} }
@ -199,7 +296,7 @@ Vec3fa Application1::renderPixelOrig(float x, float y, const ISPCCamera& camera,
Vec3fa diffuse = Material__eval(material_array, matId, brdf, wo, sample, ls.dir); Vec3fa diffuse = Material__eval(material_array, matId, brdf, wo, sample, ls.dir);
/* initialize shadow ray */ /* initialize shadow ray */
Ray shadow(sample.P, ls.dir, 0.001f, ls.dist, 0.0f); Ray shadow(sample.P, ls.dir, EPS, ls.dist - EPS, 0.0f);
/* trace shadow ray */ /* trace shadow ray */
RTCOccludedArguments sargs; RTCOccludedArguments sargs;

View file

@ -12,6 +12,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 renderPixelPathTracer(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler); Vec3fa renderPixelPathTracer(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler);
Vec3fa renderPixelNextEventEstimation(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler);
void drawGUI() override { void drawGUI() override {
ImGui::ColorEdit3("Color", colorLight); ImGui::ColorEdit3("Color", colorLight);
@ -20,8 +21,8 @@ private:
ray_depth = 1; ray_depth = 1;
} }
const char* items[] = {"Original", "Path Tracer"}; const char* items[] = {"Original", "Path Tracer", "Next Event Estimation"};
ImGui::Combo("Version", &selected, items, 2); ImGui::Combo("Version", &selected, items, 3);
const char* scenes[] = {"Cornell", "Veach"}; const char* scenes[] = {"Cornell", "Veach"};
int oldscene = scene; int oldscene = scene;

View file

@ -253,7 +253,7 @@ struct RenderScene {
else if (auto light = in.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::PointLight> >()) else if (auto light = in.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::PointLight> >())
PointLight_set(out, light->light.P, light->light.I, 0.f); PointLight_set(out, light->light.P, light->light.I, 0.f);
else if (auto light = in.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::QuadLight> >()) else if (auto light = in.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::QuadLight> >())
QuadLight_set(out, light->light.v0,light->light.v1-light->light.v0,light->light.v2-light->light.v0,light->light.L); QuadLight_set(out, light->light.v0,light->light.v3-light->light.v0,light->light.v2-light->light.v0,light->light.L);
} }
RTCScene scene; RTCScene scene;