add dummy global illum

This commit is contained in:
Shuo Feng 2024-03-20 01:07:39 -04:00
parent bb70580274
commit 5cf306cbbe
Signed by: sfeng
GPG key ID: 1E83AE6CD1C037B1
4 changed files with 84 additions and 22 deletions

View file

@ -20,6 +20,8 @@ Vector3f Light::is() const { return is_; }
bool Light::isUse() const { return use; } bool Light::isUse() const { return use; }
Vector3f PointLight::getCenter() const { return center; }
Vector3f PointLight::illumination(const HitRecord &hit, Vector3f PointLight::illumination(const HitRecord &hit,
const vector<Geometry *> &geometries) const { const vector<Geometry *> &geometries) const {
Vector3f shadingPoint = hit.point(); Vector3f shadingPoint = hit.point();
@ -46,6 +48,10 @@ Vector3f PointLight::illumination(const HitRecord &hit,
return specular_ + ambient_ + diffuse_; return specular_ + ambient_ + diffuse_;
} }
Vector3f AreaLight::getCenter() const {
return p1 + (p4 - p1) / 2 + (p2 - p1) / 2;
}
Vector3f AreaLight::illumination(const HitRecord &hit, Vector3f AreaLight::illumination(const HitRecord &hit,
const vector<Geometry *> &geometries) const { const vector<Geometry *> &geometries) const {
Vector3f u = p4 - p1; Vector3f u = p4 - p1;
@ -54,7 +60,7 @@ Vector3f AreaLight::illumination(const HitRecord &hit,
Vector3f color = Vector3f::Zero(); Vector3f color = Vector3f::Zero();
if (useCenter) { if (useCenter) {
color += PointLight(*this, p1 + (u + v) / 2).illumination(hit, geometries); color += PointLight(*this, getCenter()).illumination(hit, geometries);
} else { } else {
for (int y = 0; y < gridSize; ++y) for (int y = 0; y < gridSize; ++y)
for (int x = 0; x < gridSize; ++x) { for (int x = 0; x < gridSize; ++x) {

View file

@ -18,6 +18,7 @@ public:
virtual ~Light() = default; virtual ~Light() = default;
virtual Vector3f illumination(const HitRecord &, virtual Vector3f illumination(const HitRecord &,
const vector<Geometry *> &) const = 0; const vector<Geometry *> &) const = 0;
virtual Vector3f getCenter() const = 0;
protected: protected:
Light(Type type, const Vector3f &id, const Vector3f &is) Light(Type type, const Vector3f &id, const Vector3f &is)
@ -36,6 +37,7 @@ public:
void setGridSize(unsigned int); void setGridSize(unsigned int);
void setUseCenter(bool); void setUseCenter(bool);
void setIsUse(bool); void setIsUse(bool);
Type type() const;
Vector3f id() const; Vector3f id() const;
Vector3f is() const; Vector3f is() const;
bool isUse() const; bool isUse() const;
@ -52,6 +54,9 @@ public:
private: private:
Vector3f p1, p2, p3, p4; Vector3f p1, p2, p3, p4;
public:
Vector3f getCenter() const override;
}; };
class PointLight : public Light { class PointLight : public Light {
@ -67,6 +72,9 @@ public:
private: private:
Vector3f center; Vector3f center;
public:
Vector3f getCenter() const override;
}; };
#endif // !LIGHT_H_ #endif // !LIGHT_H_

View file

@ -1,5 +1,6 @@
#include "RayTracer.h" #include "RayTracer.h"
#include "HitRecord.h" #include "HitRecord.h"
#include "Light.h"
#include "Output.h" #include "Output.h"
#include "Parser.h" #include "Parser.h"
#include "Progress.h" #include "Progress.h"
@ -7,6 +8,7 @@
#include "Ray.h" #include "Ray.h"
#include <Eigen/Core> #include <Eigen/Core>
#include <algorithm>
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <queue> #include <queue>
@ -89,26 +91,22 @@ void RayTracer::render() {
for (int j = 0; j < gridHeight; ++j) for (int j = 0; j < gridHeight; ++j)
for (int i = 0; i < gridWidth; ++i) { for (int i = 0; i < gridWidth; ++i) {
Ray ray = getRay(x, y, i, j); Ray ray = getRay(x, y, i, j);
utils::Optional<Vector3f> result = trace(ray); for (int rayNum = 0; rayNum < raysPerPixel; ++rayNum) {
if (result.hasValue()) { utils::Optional<Vector3f> result = trace(ray);
accumulate += result.value() * raysPerPixel; if (result.hasValue()) {
success += raysPerPixel; accumulate += result.value();
success++;
}
} }
} }
if (!success) if (!success)
color = accumulate / success; color = accumulate / success;
} else { } else {
Ray ray = getRay(x, y); Ray ray = getRay(x, y);
priority_queue<HitRecord> records; Optional<HitRecord> hitRecord = getHitRecord(ray);
for (auto g : geometries) {
Optional<float> t = g->intersect(ray);
if (t.hasValue())
records.push(HitRecord(t.value(), ray, g));
}
if (!records.empty()) { if (hitRecord.hasValue()) {
HitRecord hit = records.top(); HitRecord hit = hitRecord.value();
hit.calcNormal();
color = calculateColor(hit, y * width + x); color = calculateColor(hit, y * width + x);
} }
} }
@ -130,6 +128,33 @@ Vector3f RayTracer::calculateColor(const HitRecord &hit, int i) const {
return result; return result;
} }
/**
* Find the nearest geometry to intersect
*/
Optional<HitRecord> RayTracer::getHitRecord(Ray r) const {
priority_queue<HitRecord> records;
for (auto g : geometries) {
Optional<float> t = g->intersect(r);
if (t.hasValue())
records.push(HitRecord(t.value(), r, g));
}
if (!records.empty()) {
HitRecord result = records.top();
result.calcNormal();
return Optional<HitRecord>(result);
}
return Optional<HitRecord>::nullopt;
}
Light *RayTracer::singleLightSource() const {
for (auto light : lights)
if (light->isUse())
return light;
return nullptr;
}
// helper functions // helper functions
Ray getRay(int x, int y) { Ray getRay(int x, int y) {
using namespace camera; using namespace camera;
@ -151,21 +176,39 @@ void writeColor(int i, const Vector3f &color) {
Output::current->b(i, color.z()); Output::current->b(i, color.z());
} }
Vector3f trace(Ray r, int bounce, float prob) { Vector3f RayTracer::trace(HitRecord hit, int bounce, float prob) const {
float dice = utils::Random::get(); float dice = utils::Random::get();
if (bounce && (dice > prob)) { if (bounce && (dice > prob)) {
return Vector3f(1, 0, 1).array() * trace(r, bounce - 1, prob).array(); return Vector3f(1, 0, 1).array() * trace(hit, bounce - 1, prob).array();
} else {
Light *light = singleLightSource();
Vector3f point = hit.point();
Vector3f direction = (light->getCenter() - point).normalized();
Ray shadowRay(point, direction);
Geometry *geometry = hit.geometry();
for (auto g : geometries)
if (g != geometry && g->intersect(shadowRay).hasValue() &&
g->type() == Geometry::Type::SPHERE)
return Vector3f::Zero();
return geometry->cd().array() * light->id().array() *
std::max(0.0f, hit.normal().dot(direction));
} }
return Vector3f(1, 1, 1); return Vector3f(1, 1, 1);
} }
utils::Optional<Vector3f> trace(Ray r) { utils::Optional<Vector3f> RayTracer::trace(Ray r) const {
Vector3f color = Optional<HitRecord> hitRecord = getHitRecord(r);
trace(r, Scene::current->maxBounce(), Scene::current->probTerminate()); if (hitRecord.hasValue()) {
Vector3f color = trace(hitRecord.value(), Scene::current->maxBounce(),
Scene::current->probTerminate());
if (color != Vector3f::Zero()) if (color != Vector3f::Zero())
return utils::Optional<Vector3f>(color); return utils::Optional<Vector3f>(color);
}
return utils::Optional<Vector3f>::nullopt; return utils::Optional<Vector3f>::nullopt;
} }

View file

@ -3,6 +3,7 @@
#include "../external/json.hpp" #include "../external/json.hpp"
#include "Geometry.h" #include "Geometry.h"
#include "HitRecord.h"
#include "Light.h" #include "Light.h"
#include "Output.h" #include "Output.h"
#include "Scene.h" #include "Scene.h"
@ -22,8 +23,12 @@ private:
std::vector<Output *> outputs; std::vector<Output *> outputs;
void parse(); void parse();
Vector3f calculateColor(const HitRecord &, int) const;
void render(); void render();
Optional<HitRecord> getHitRecord(Ray) const;
Vector3f calculateColor(const HitRecord &, int) const;
Light *singleLightSource() const;
Optional<Vector3f> trace(Ray) const;
Vector3f trace(HitRecord, int, float) const;
}; };
#endif // !RAY_TRACER_H_ #endif // !RAY_TRACER_H_