Add path tracing implementation for Assignment1.

This commit is contained in:
hal8174 2024-05-02 12:37:21 +02:00
parent 0653874165
commit 0b132ea4e7
2 changed files with 111 additions and 3 deletions

View file

@ -1,4 +1,10 @@
#include "Application1.h" #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() { void Application1::initScene() {
Data_Constructor(&data, 1, 8); Data_Constructor(&data, 1, 8);
@ -62,8 +68,82 @@ void Application1::veachScene() {
scene = nullptr; scene = nullptr;
} }
/* task that renders a single screen tile */
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) {
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 *> 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 */ /* radiance accumulator and weight */
Vec3fa L = Vec3fa(0.0f); Vec3fa L = Vec3fa(0.0f);
Vec3fa Lw = Vec3fa(1.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); Material__preprocess(material_array, matId, brdf, wo, sample);
/* sample BRDF at hit point */ /* sample BRDF at hit point */
Sample3f wi1; // Sample3f wi1;
Material__sample(material_array, matId, brdf, Lw, wo, sample, wi1, RandomSampler_get2D(sampler)); // Material__sample(material_array, matId, brdf, Lw, wo, sample, wi1, RandomSampler_get2D(sampler));
int id = (int)(RandomSampler_get1D(sampler) * data.scene->lights.size()); int id = (int)(RandomSampler_get1D(sampler) * data.scene->lights.size());
if (id == data.scene->lights.size()) if (id == data.scene->lights.size())

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "helper.hpp" #include "helper.hpp"
#include "imgui.h"
class Application1 : public Application { class Application1 : public Application {
@ -9,8 +10,31 @@ public:
private: 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 renderPixelPathTracer(float x, float y, const ISPCCamera& camera, RayStats& stats, RandomSampler& sampler);
void drawGUI() override { 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; void initScene() override;
@ -20,4 +44,8 @@ private:
void veachScene(); void veachScene();
float colorLight[3] = {1.0f, 1.0f, 1.0f}; float colorLight[3] = {1.0f, 1.0f, 1.0f};
int ray_depth = 5;
int selected = 0;
int scene = 0;
}; };