rendering-in-cgi/Assignments/Assignment1/Application1.cpp
2024-04-23 10:33:00 +02:00

121 lines
4.3 KiB
C++

#include "Application1.h"
void Application1::initScene() {
Data_Constructor(&data, 1, 8);
/* select scene here */
standardScene();
// standardScenewithAreaLight();
}
void Application1::standardScene() {
FileName file = workingDir + FileName("Framework/scenes/cornell_box.obj");
/* set default camera */
camera.from = Vec3fa(278, 273, -800);
camera.to = Vec3fa(278, 273, 0);
Ref<SceneGraph::GroupNode> sceneGraph = loadOBJ(file, false).cast<SceneGraph::GroupNode>();
sceneGraph->add(new SceneGraph::LightNodeImpl<SceneGraph::PointLight>(
SceneGraph::PointLight(Vec3fa(213, 300, 227), Vec3fa(100000, 100000, 100000))));
Ref<SceneGraph::GroupNode> flattened_scene = SceneGraph::flatten(sceneGraph, SceneGraph::INSTANCING_NONE);
Scene* scene = new Scene;
scene->add(flattened_scene);
sceneGraph = nullptr;
flattened_scene = nullptr;
auto renderScene = new RenderScene(g_device, scene);
g_render_scene = renderScene;
data.scene = renderScene;
scene = nullptr;
}
void Application1::standardScenewithAreaLight() {
FileName file = workingDir + FileName("Framework/scenes/cornell_box.obj");
/* set default camera */
camera.from = Vec3fa(278, 273, -800);
camera.to = Vec3fa(278, 273, 0);
Ref<SceneGraph::GroupNode> sceneGraph = loadOBJ(file, false).cast<SceneGraph::GroupNode>();
sceneGraph->add(new SceneGraph::LightNodeImpl<SceneGraph::QuadLight>(
SceneGraph::QuadLight(Vec3fa(343.0, 548.0, 227.0), Vec3fa(343.0, 548.0, 332.0), Vec3fa(213.0, 548.0, 332.0),
Vec3fa(213.0, 548.0, 227.0), Vec3fa(100000, 100000, 100000))));
Ref<SceneGraph::GroupNode> flattened_scene = SceneGraph::flatten(sceneGraph, SceneGraph::INSTANCING_NONE);
Scene* scene = new Scene;
scene->add(flattened_scene);
sceneGraph = nullptr;
flattened_scene = nullptr;
auto renderScene = new RenderScene(g_device, scene);
g_render_scene = renderScene;
data.scene = renderScene;
scene = nullptr;
}
/* task that renders a single screen tile */
Vec3fa Application1::renderPixel(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);
/* 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) {
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;
sample.Ng = face_forward(ray.dir, normalize(sample.Ng));
sample.Ns = face_forward(ray.dir, normalize(sample.Ns));
/* 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 */
Sample3f wi1;
Material__sample(material_array, matId, brdf, Lw, wo, sample, wi1, RandomSampler_get2D(sampler));
const Light* l = data.scene->lights[0];
Light_SampleRes ls = Lights_sample(l, sample, RandomSampler_get2D(sampler));
Vec3f lightColor = {colorLight[0], colorLight[1], colorLight[2]};
Vec3fa diffuse = Material__eval(material_array, matId, brdf, wo, sample, ls.dir);
L += diffuse;
/* initialize shadow ray */
Ray shadow(sample.P, ls.dir, 0.001f, ls.dist, 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 += ls.weight * lightColor * 0.1f;
}
}
return L;
}