mirror of
https://github.com/vonhyou/ray-tracer-comp371.git
synced 2025-06-08 07:22:01 +00:00
commit
b38e8bc964
14 changed files with 151 additions and 136 deletions
|
@ -3,22 +3,23 @@
|
||||||
#include <Eigen/Dense>
|
#include <Eigen/Dense>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
Vector3f Geometry::diffuse() const { return cd; }
|
Vector3f Geometry::cd() const { return cd_; }
|
||||||
Vector3f Geometry::specular() const { return cs; }
|
Vector3f Geometry::cs() const { return cs_; }
|
||||||
Vector3f Geometry::ambient() const { return ca; }
|
Vector3f Geometry::ca() const { return ca_; }
|
||||||
float Geometry::coefDiffuse() const { return kd; }
|
float Geometry::kd() const { return kd_; }
|
||||||
float Geometry::coefSpecular() const { return ks; }
|
float Geometry::ks() const { return ks_; }
|
||||||
float Geometry::coefAmbient() const { return ka; }
|
float Geometry::ka() const { return ka_; }
|
||||||
float Geometry::getPhong() const { return phong; }
|
float Geometry::phong() const { return phong_; }
|
||||||
|
Geometry::Type Geometry::type() const { return type_; }
|
||||||
|
|
||||||
void Geometry::setTransform(const Matrix4f &transform) {
|
void Geometry::setTransform(const Matrix4f &transform) {
|
||||||
this->transform = transform;
|
this->transform = transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<float> Sphere::intersect(const Ray &r) const {
|
Optional<float> Sphere::intersect(const Ray &r) const {
|
||||||
Vector3f originCenter = r.getOrigin() - center;
|
Vector3f originCenter = r.origin() - center;
|
||||||
float a = r.getDirection().dot(r.getDirection());
|
float a = r.direction().dot(r.direction());
|
||||||
float b = 2.0f * originCenter.dot(r.getDirection());
|
float b = 2.0f * originCenter.dot(r.direction());
|
||||||
float c = originCenter.dot(originCenter) - radius * radius;
|
float c = originCenter.dot(originCenter) - radius * radius;
|
||||||
|
|
||||||
float delta = b * b - 4 * a * c;
|
float delta = b * b - 4 * a * c;
|
||||||
|
@ -35,7 +36,7 @@ Optional<float> Sphere::intersect(const Ray &r) const {
|
||||||
return Optional<float>::nullopt;
|
return Optional<float>::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f Sphere::getNormal(const Vector3f &p) const {
|
Vector3f Sphere::normal(const Vector3f &p) const {
|
||||||
return (p - center).normalized();
|
return (p - center).normalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,18 +52,18 @@ bool isInRectangle(const Vector3f &p, const Vector3f &a, const Vector3f &b,
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<float> Rectangle::intersect(const Ray &r) const {
|
Optional<float> Rectangle::intersect(const Ray &r) const {
|
||||||
float denom = normal.dot(r.getDirection());
|
float denom = normal_.dot(r.direction());
|
||||||
if (abs(denom) < 1e-6f)
|
if (abs(denom) < 1e-6f)
|
||||||
return Optional<float>::nullopt;
|
return Optional<float>::nullopt;
|
||||||
|
|
||||||
float t = -normal.dot(r.getOrigin() - p1) / denom;
|
float t = -normal_.dot(r.origin() - p1) / denom;
|
||||||
if (t <= 0)
|
if (t <= 0)
|
||||||
return Optional<float>::nullopt;
|
return Optional<float>::nullopt;
|
||||||
|
|
||||||
Vector3f p = r.getOrigin() + t * r.getDirection();
|
Vector3f p = r.origin() + t * r.direction();
|
||||||
|
|
||||||
return isInRectangle(p, p1, p2, p3, p4, normal) ? Optional<float>(t)
|
return isInRectangle(p, p1, p2, p3, p4, normal_) ? Optional<float>(t)
|
||||||
: Optional<float>::nullopt;
|
: Optional<float>::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f Rectangle::getNormal(const Vector3f &p) const { return normal; }
|
Vector3f Rectangle::normal(const Vector3f &p) const { return normal_; }
|
||||||
|
|
|
@ -19,27 +19,29 @@ public:
|
||||||
|
|
||||||
virtual ~Geometry() = default;
|
virtual ~Geometry() = default;
|
||||||
virtual Optional<float> intersect(const Ray &) const = 0;
|
virtual Optional<float> intersect(const Ray &) const = 0;
|
||||||
virtual Vector3f getNormal(const Vector3f &) const = 0;
|
virtual Vector3f normal(const Vector3f &) const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Geometry(Type type, float ka, float kd, float ks, const Vector3f &ca,
|
Geometry(Type type, float ka, float kd, float ks, const Vector3f &ca,
|
||||||
const Vector3f &cd, const Vector3f &cs, float pc)
|
const Vector3f &cd, const Vector3f &cs, float pc)
|
||||||
: type(type), ka(ka), kd(kd), ks(ks), ca(ca), cd(cd), cs(cs), phong(pc) {}
|
: type_(type), ka_(ka), kd_(kd), ks_(ks), ca_(ca), cd_(cd), cs_(cs),
|
||||||
|
phong_(pc) {}
|
||||||
|
|
||||||
Type type;
|
Type type_;
|
||||||
float ka, kd, ks; // coefficients for ambient, diffuse and specular
|
float ka_, kd_, ks_; // coefficients for ambient, diffuse and specular
|
||||||
Vector3f ca, cd, cs; // ambient, diffuse and specular reflection color
|
Vector3f ca_, cd_, cs_; // ambient, diffuse and specular reflection color
|
||||||
float phong; // phone coefficient, for `pc`
|
float phong_; // phone coefficient, for `pc`
|
||||||
Matrix4f transform = Matrix4f::Identity();
|
Matrix4f transform = Matrix4f::Identity();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Vector3f diffuse() const;
|
Vector3f cd() const;
|
||||||
Vector3f specular() const;
|
Vector3f cs() const;
|
||||||
Vector3f ambient() const;
|
Vector3f ca() const;
|
||||||
float coefDiffuse() const;
|
float kd() const;
|
||||||
float coefSpecular() const;
|
float ks() const;
|
||||||
float coefAmbient() const;
|
float ka() const;
|
||||||
float getPhong() const;
|
float phong() const;
|
||||||
|
Type type() const;
|
||||||
void setTransform(const Matrix4f &);
|
void setTransform(const Matrix4f &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ public:
|
||||||
center(center) {}
|
center(center) {}
|
||||||
|
|
||||||
Optional<float> intersect(const Ray &) const override;
|
Optional<float> intersect(const Ray &) const override;
|
||||||
Vector3f getNormal(const Vector3f &) const override;
|
Vector3f normal(const Vector3f &) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float radius;
|
float radius;
|
||||||
|
@ -64,14 +66,14 @@ public:
|
||||||
const Vector3f &cs, float pc, const Vector3f &p1,
|
const Vector3f &cs, float pc, const Vector3f &p1,
|
||||||
const Vector3f &p2, const Vector3f &p3, const Vector3f &p4)
|
const Vector3f &p2, const Vector3f &p3, const Vector3f &p4)
|
||||||
: Geometry(Type::RECTANGLE, ka, kd, ks, ca, cd, cs, pc), p1(p1), p2(p2),
|
: Geometry(Type::RECTANGLE, ka, kd, ks, ca, cd, cs, pc), p1(p1), p2(p2),
|
||||||
p3(p3), p4(p4), normal((p2 - p1).cross(p3 - p1).normalized()) {}
|
p3(p3), p4(p4), normal_((p2 - p1).cross(p3 - p1).normalized()) {}
|
||||||
|
|
||||||
Optional<float> intersect(const Ray &) const override;
|
Optional<float> intersect(const Ray &) const override;
|
||||||
Vector3f getNormal(const Vector3f &) const override;
|
Vector3f normal(const Vector3f &) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector3f p1, p2, p3, p4;
|
Vector3f p1, p2, p3, p4;
|
||||||
Vector3f normal;
|
Vector3f normal_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !GEOMETRY_H_
|
#endif // !GEOMETRY_H_
|
||||||
|
|
|
@ -4,16 +4,16 @@ bool HitRecord::operator<(const HitRecord &other) const {
|
||||||
return this->t > other.t; // to get the nearest t
|
return this->t > other.t; // to get the nearest t
|
||||||
}
|
}
|
||||||
|
|
||||||
Geometry *HitRecord::geometry() const { return g; }
|
Geometry *HitRecord::geometry() const { return geometry_; }
|
||||||
|
|
||||||
Vector3f HitRecord::getPoint() const {
|
Vector3f HitRecord::point() const {
|
||||||
return r.getOrigin() + t * r.getDirection();
|
return ray_.origin() + t * ray_.direction();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f HitRecord::viewDirection() const {
|
Vector3f HitRecord::viewDirection() const {
|
||||||
return -r.getDirection().normalized();
|
return -ray_.direction().normalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f HitRecord::normal() const { return n; }
|
Vector3f HitRecord::normal() const { return normal_; }
|
||||||
|
|
||||||
void HitRecord::calcNormal() { n = g->getNormal(getPoint()); }
|
void HitRecord::calcNormal() { normal_ = geometry_->normal(point()); }
|
||||||
|
|
|
@ -9,18 +9,18 @@ using Eigen::Vector3f;
|
||||||
|
|
||||||
class HitRecord {
|
class HitRecord {
|
||||||
public:
|
public:
|
||||||
HitRecord(float t, const Ray &r, Geometry *g) : t(t), r(r), g(g) {}
|
HitRecord(float t, const Ray &r, Geometry *g) : t(t), ray_(r), geometry_(g) {}
|
||||||
bool operator<(const HitRecord &) const;
|
bool operator<(const HitRecord &) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float t;
|
float t;
|
||||||
Ray r;
|
Ray ray_;
|
||||||
Vector3f n;
|
Vector3f normal_;
|
||||||
Geometry *g;
|
Geometry *geometry_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Geometry *geometry() const;
|
Geometry *geometry() const;
|
||||||
Vector3f getPoint() const;
|
Vector3f point() const;
|
||||||
Vector3f viewDirection() const;
|
Vector3f viewDirection() const;
|
||||||
Vector3f normal() const;
|
Vector3f normal() const;
|
||||||
void calcNormal();
|
void calcNormal();
|
||||||
|
|
29
src/Light.cc
29
src/Light.cc
|
@ -1,4 +1,6 @@
|
||||||
#include "Light.h"
|
#include "Light.h"
|
||||||
|
#include "Scene.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
@ -12,34 +14,34 @@ void Light::setUseCenter(bool useCenter) { this->useCenter = useCenter; }
|
||||||
|
|
||||||
void Light::setIsUse(bool isUse) { this->use = isUse; }
|
void Light::setIsUse(bool isUse) { this->use = isUse; }
|
||||||
|
|
||||||
Vector3f Light::getDiffuse() const { return diffuse; }
|
Vector3f Light::id() const { return id_; }
|
||||||
|
|
||||||
Vector3f Light::getSpecular() const { return specular; }
|
Vector3f Light::is() const { return is_; }
|
||||||
|
|
||||||
bool Light::isUse() const { return use; }
|
bool Light::isUse() const { return use; }
|
||||||
|
|
||||||
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.getPoint();
|
Vector3f shadingPoint = hit.point();
|
||||||
Vector3f rayDirection = (center - shadingPoint).normalized();
|
Vector3f rayDirection = (center - shadingPoint).normalized();
|
||||||
Geometry *geometry = hit.geometry();
|
Geometry *geometry = hit.geometry();
|
||||||
Ray shadowRay(shadingPoint, rayDirection);
|
Ray shadowRay(shadingPoint, rayDirection);
|
||||||
|
|
||||||
for (auto g : geometries)
|
for (auto g : geometries)
|
||||||
if (g != geometry && g->intersect(shadowRay).hasValue())
|
if (g != geometry && g->intersect(shadowRay).hasValue() &&
|
||||||
|
g->type() == Geometry::Type::SPHERE)
|
||||||
return Vector3f::Zero();
|
return Vector3f::Zero();
|
||||||
|
|
||||||
Vector3f ambient_ = geometry->coefAmbient() * geometry->ambient();
|
Vector3f ambient_ =
|
||||||
|
geometry->ka() * geometry->ca().array() * Scene::current->ai().array();
|
||||||
|
|
||||||
Vector3f diffuse_ = geometry->coefDiffuse() * geometry->diffuse().array() *
|
Vector3f diffuse_ = geometry->kd() * geometry->cd().array() * id_.array() *
|
||||||
diffuse.array() *
|
|
||||||
std::max(0.0f, hit.normal().dot(rayDirection));
|
std::max(0.0f, hit.normal().dot(rayDirection));
|
||||||
|
|
||||||
Vector3f halfWay = (hit.viewDirection() + rayDirection).normalized();
|
Vector3f halfWay = (hit.viewDirection() + rayDirection).normalized();
|
||||||
Vector3f specular_ =
|
Vector3f specular_ =
|
||||||
geometry->coefSpecular() * geometry->specular().array() *
|
geometry->ks() * geometry->cs().array() * is_.array() *
|
||||||
specular.array() *
|
pow(std::max(0.0f, hit.normal().dot(halfWay)), geometry->phong());
|
||||||
pow(std::max(0.0f, hit.normal().dot(halfWay)), geometry->getPhong());
|
|
||||||
|
|
||||||
return specular_ + ambient_ + diffuse_;
|
return specular_ + ambient_ + diffuse_;
|
||||||
}
|
}
|
||||||
|
@ -55,9 +57,12 @@ Vector3f AreaLight::illumination(const HitRecord &hit,
|
||||||
color += PointLight(*this, p1 + (u + v) / 2).illumination(hit, geometries);
|
color += PointLight(*this, p1 + (u + v) / 2).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) {
|
||||||
color += PointLight(*this, p1 + (u * x + v * y) / gridSize)
|
Vector3f contribution =
|
||||||
|
PointLight(*this, p1 + (u * x + v * y) / gridSize)
|
||||||
.illumination(hit, geometries);
|
.illumination(hit, geometries);
|
||||||
|
color += contribution;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return color / gridSize / gridSize;
|
return color / gridSize / gridSize;
|
||||||
|
|
14
src/Light.h
14
src/Light.h
|
@ -21,11 +21,11 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Light(Type type, const Vector3f &id, const Vector3f &is)
|
Light(Type type, const Vector3f &id, const Vector3f &is)
|
||||||
: type(type), diffuse(id), specular(is) {}
|
: type_(type), id_(id), is_(is) {}
|
||||||
|
|
||||||
Type type;
|
Type type_;
|
||||||
Vector3f diffuse;
|
Vector3f id_;
|
||||||
Vector3f specular;
|
Vector3f is_;
|
||||||
Matrix4f transform = Matrix4f::Identity(); // optional member `transform`
|
Matrix4f transform = Matrix4f::Identity(); // optional member `transform`
|
||||||
unsigned int gridSize = 0; // optional member `n`
|
unsigned int gridSize = 0; // optional member `n`
|
||||||
bool useCenter = false; // optional member `usecenter`
|
bool useCenter = false; // optional member `usecenter`
|
||||||
|
@ -36,8 +36,8 @@ public:
|
||||||
void setGridSize(unsigned int);
|
void setGridSize(unsigned int);
|
||||||
void setUseCenter(bool);
|
void setUseCenter(bool);
|
||||||
void setIsUse(bool);
|
void setIsUse(bool);
|
||||||
Vector3f getDiffuse() const;
|
Vector3f id() const;
|
||||||
Vector3f getSpecular() const;
|
Vector3f is() const;
|
||||||
bool isUse() const;
|
bool isUse() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ public:
|
||||||
: Light(Type::Point, id, is), center(center) {}
|
: Light(Type::Point, id, is), center(center) {}
|
||||||
|
|
||||||
PointLight(const AreaLight &al, const Vector3f ¢er)
|
PointLight(const AreaLight &al, const Vector3f ¢er)
|
||||||
: PointLight(al.getDiffuse(), al.getSpecular(), center) {}
|
: PointLight(al.id(), al.is(), center) {}
|
||||||
|
|
||||||
virtual Vector3f illumination(const HitRecord &,
|
virtual Vector3f illumination(const HitRecord &,
|
||||||
const vector<Geometry *> &) const override;
|
const vector<Geometry *> &) const override;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
Output *Output::current = nullptr;
|
||||||
|
|
||||||
void Output::write() {
|
void Output::write() {
|
||||||
std::ofstream fout(path, std::ios_base::out | std::ios_base::binary);
|
std::ofstream fout(path, std::ios_base::out | std::ios_base::binary);
|
||||||
fout << "P6\n" << width << ' ' << height << '\n' << "255" << std::endl;
|
fout << "P6\n" << width << ' ' << height << '\n' << "255" << std::endl;
|
||||||
|
|
|
@ -33,6 +33,8 @@ public:
|
||||||
float g(int) const;
|
float g(int) const;
|
||||||
void b(int, float);
|
void b(int, float);
|
||||||
float b(int) const;
|
float b(int) const;
|
||||||
|
|
||||||
|
static Output *current;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !OUTPUT_H_
|
#endif // !OUTPUT_H_
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "Ray.h"
|
#include "Ray.h"
|
||||||
|
|
||||||
Vector3f Ray::getOrigin() const { return origin; }
|
Vector3f Ray::origin() const { return origin_; }
|
||||||
|
|
||||||
Vector3f Ray::getDirection() const { return direction; }
|
Vector3f Ray::direction() const { return direction_; }
|
||||||
|
|
10
src/Ray.h
10
src/Ray.h
|
@ -7,15 +7,15 @@ using Eigen::Vector3f;
|
||||||
|
|
||||||
class Ray {
|
class Ray {
|
||||||
public:
|
public:
|
||||||
Ray(const Vector3f &o, const Vector3f &d) : origin(o), direction(d) {}
|
Ray(const Vector3f &o, const Vector3f &d) : origin_(o), direction_(d) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector3f origin;
|
Vector3f origin_;
|
||||||
Vector3f direction;
|
Vector3f direction_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Vector3f getOrigin() const;
|
Vector3f origin() const;
|
||||||
Vector3f getDirection() const;
|
Vector3f direction() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !RAY_H_
|
#endif // !RAY_H_
|
||||||
|
|
|
@ -27,27 +27,25 @@ Ray getRay(int x, int y, const Vector3f &camPos, const Vector3f &pxUpperLeft,
|
||||||
return Ray(camPos, pxUpperLeft + x * du + y * dv - camPos);
|
return Ray(camPos, pxUpperLeft + x * du + y * dv - camPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayTracer::calculateColor(const HitRecord &hit, Output *buffer, int i) {
|
void RayTracer::calculateColor(const HitRecord &hit, int i) {
|
||||||
buffer->r(i, 0);
|
Vector3f result(0, 0, 0);
|
||||||
buffer->g(i, 0);
|
|
||||||
buffer->b(i, 0);
|
|
||||||
for (auto light : lights)
|
for (auto light : lights)
|
||||||
if (light->isUse()) {
|
result += light->isUse() ? light->illumination(hit, geometries)
|
||||||
Vector3f contribution =
|
: Vector3f::Zero();
|
||||||
light->illumination(hit, geometries).cwiseMax(0.0f).cwiseMin(1.0f) /
|
|
||||||
lights.size();
|
result = result.cwiseMax(0.0f).cwiseMin(1.0f);
|
||||||
buffer->r(i, buffer->r(i) + contribution.x());
|
Output::current->r(i, result.x());
|
||||||
buffer->g(i, buffer->g(i) + contribution.y());
|
Output::current->g(i, result.y());
|
||||||
buffer->b(i, buffer->b(i) + contribution.z());
|
Output::current->b(i, result.z());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayTracer::render(Scene *scene) {
|
void RayTracer::render() {
|
||||||
int width = scene->getWidth();
|
int width = Scene::current->width();
|
||||||
int height = scene->getHeight();
|
int height = Scene::current->height();
|
||||||
Vector3f cameraPos = scene->getCenter();
|
Vector3f cameraPos = Scene::current->center();
|
||||||
Vector3f lookAt = scene->getLookAt();
|
Vector3f lookAt = Scene::current->lookAt();
|
||||||
float vpHeight = 2 * tan(scene->getFov() / 180 * M_PI / 2) * lookAt.norm();
|
float vpHeight =
|
||||||
|
2 * tan(Scene ::current->fov() / 180 * M_PI / 2) * lookAt.norm();
|
||||||
float vpWidth = vpHeight * width / height;
|
float vpWidth = vpHeight * width / height;
|
||||||
Vector3f vpU = Vector3f(vpWidth, 0, 0);
|
Vector3f vpU = Vector3f(vpWidth, 0, 0);
|
||||||
Vector3f vpV = Vector3f(0, -vpHeight, 0);
|
Vector3f vpV = Vector3f(0, -vpHeight, 0);
|
||||||
|
@ -57,8 +55,8 @@ void RayTracer::render(Scene *scene) {
|
||||||
Vector3f vpUpperLeft = cameraPos + lookAt - vpU / 2.0 - vpV / 2.0;
|
Vector3f vpUpperLeft = cameraPos + lookAt - vpU / 2.0 - vpV / 2.0;
|
||||||
Vector3f pxUpperLeft = vpUpperLeft + (du + dv) / 2.0;
|
Vector3f pxUpperLeft = vpUpperLeft + (du + dv) / 2.0;
|
||||||
|
|
||||||
Output *buffer =
|
Output::current = new Output(Scene::current->backgroundColor(),
|
||||||
new Output(scene->getBackgroundColor(), scene->getName(), width, height);
|
Scene::current->name(), width, height);
|
||||||
|
|
||||||
for (int y = 0; y < height; ++y)
|
for (int y = 0; y < height; ++y)
|
||||||
for (int x = 0; x < width; ++x) {
|
for (int x = 0; x < width; ++x) {
|
||||||
|
@ -73,11 +71,9 @@ void RayTracer::render(Scene *scene) {
|
||||||
if (!records.empty()) {
|
if (!records.empty()) {
|
||||||
HitRecord hit = records.top();
|
HitRecord hit = records.top();
|
||||||
hit.calcNormal();
|
hit.calcNormal();
|
||||||
calculateColor(hit, buffer, y * width + x);
|
calculateColor(hit, y * width + x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outputs.push_back(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RayTracer::output() {
|
void RayTracer::output() {
|
||||||
|
@ -88,8 +84,9 @@ void RayTracer::output() {
|
||||||
void RayTracer::run() {
|
void RayTracer::run() {
|
||||||
parse();
|
parse();
|
||||||
|
|
||||||
for (auto scene : scenes)
|
for (auto scene : scenes) {
|
||||||
render(scene);
|
Scene::current = scene;
|
||||||
|
render();
|
||||||
output();
|
Output::current->write();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ private:
|
||||||
std::vector<Output *> outputs;
|
std::vector<Output *> outputs;
|
||||||
|
|
||||||
void parse();
|
void parse();
|
||||||
void calculateColor(const HitRecord &, Output *, int);
|
void calculateColor(const HitRecord &, int);
|
||||||
void render(Scene *);
|
void render();
|
||||||
void output();
|
void output();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
28
src/Scene.cc
28
src/Scene.cc
|
@ -1,33 +1,37 @@
|
||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
|
|
||||||
string Scene::getName() const { return name; }
|
Scene *Scene::current = nullptr;
|
||||||
|
|
||||||
int Scene::getWidth() { return width; }
|
string Scene::name() const { return name_; }
|
||||||
|
|
||||||
int Scene::getHeight() { return height; }
|
int Scene::width() { return width_; }
|
||||||
|
|
||||||
float Scene::getFov() { return fov; }
|
int Scene::height() { return height_; }
|
||||||
|
|
||||||
Vector3f Scene::getCenter() const { return center; }
|
float Scene::fov() { return fov_; }
|
||||||
|
|
||||||
Vector3f Scene::getUpVector() const { return up; }
|
Vector3f Scene::ai() const { return ai_; }
|
||||||
|
|
||||||
Vector3f Scene::getLookAt() const { return lookAt; }
|
Vector3f Scene::center() const { return center_; }
|
||||||
|
|
||||||
Vector3f Scene::getBackgroundColor() const { return backgroundColor; }
|
Vector3f Scene::up() const { return up_; }
|
||||||
|
|
||||||
|
Vector3f Scene::lookAt() const { return lookAt_; }
|
||||||
|
|
||||||
|
Vector3f Scene::backgroundColor() const { return bgc_; }
|
||||||
|
|
||||||
void Scene::setRaysPerPixel(const Eigen::VectorXi &raysPerPixel) {
|
void Scene::setRaysPerPixel(const Eigen::VectorXi &raysPerPixel) {
|
||||||
this->raysPerPixel = raysPerPixel;
|
this->raysPerPixel_ = raysPerPixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::setAntialiasing(bool antialiasing) {
|
void Scene::setAntialiasing(bool antialiasing) {
|
||||||
this->antialiasing = antialiasing;
|
this->antialiasing_ = antialiasing;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::setTwoSideRender(bool twoSideRender) {
|
void Scene::setTwoSideRender(bool twoSideRender) {
|
||||||
this->twoSideRender = twoSideRender;
|
this->twoSideRender_ = twoSideRender;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::setGlobalIllum(bool globalIllum) {
|
void Scene::setGlobalIllum(bool globalIllum) {
|
||||||
this->globalIllum = globalIllum;
|
this->globalIllum_ = globalIllum;
|
||||||
}
|
}
|
||||||
|
|
48
src/Scene.h
48
src/Scene.h
|
@ -12,38 +12,40 @@ public:
|
||||||
Scene(string name, int width, int height, float fov, const Vector3f ¢er,
|
Scene(string name, int width, int height, float fov, const Vector3f ¢er,
|
||||||
const Vector3f &up, const Vector3f &lookAt, const Vector3f &ai,
|
const Vector3f &up, const Vector3f &lookAt, const Vector3f &ai,
|
||||||
const Vector3f &bgc)
|
const Vector3f &bgc)
|
||||||
: name(name), width(width), height(height), fov(fov), center(center),
|
: name_(name), width_(width), height_(height), fov_(fov), center_(center),
|
||||||
up(up), lookAt(lookAt), ai(ai), backgroundColor(bgc) {}
|
up_(up), lookAt_(lookAt), ai_(ai), bgc_(bgc) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
string name;
|
string name_;
|
||||||
int width;
|
int width_;
|
||||||
int height;
|
int height_;
|
||||||
float fov;
|
float fov_;
|
||||||
Vector3f center;
|
Vector3f center_;
|
||||||
Vector3f up;
|
Vector3f up_;
|
||||||
Vector3f lookAt;
|
Vector3f lookAt_;
|
||||||
Vector3f ai; // ambient intensity
|
Vector3f ai_; // ambient intensity
|
||||||
Vector3f backgroundColor;
|
Vector3f bgc_;
|
||||||
|
|
||||||
Eigen::VectorXi raysPerPixel;
|
Eigen::VectorXi raysPerPixel_;
|
||||||
bool antialiasing = false;
|
bool antialiasing_ = false;
|
||||||
bool twoSideRender = false;
|
bool twoSideRender_ = false;
|
||||||
bool globalIllum = false;
|
bool globalIllum_ = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
string getName() const;
|
string name() const;
|
||||||
int getWidth();
|
int width();
|
||||||
int getHeight();
|
int height();
|
||||||
float getFov();
|
float fov();
|
||||||
Vector3f getCenter() const;
|
Vector3f ai() const;
|
||||||
Vector3f getUpVector() const;
|
Vector3f center() const;
|
||||||
Vector3f getLookAt() const;
|
Vector3f up() const;
|
||||||
Vector3f getBackgroundColor() const;
|
Vector3f lookAt() const;
|
||||||
|
Vector3f backgroundColor() const;
|
||||||
void setRaysPerPixel(const Eigen::VectorXi &);
|
void setRaysPerPixel(const Eigen::VectorXi &);
|
||||||
void setAntialiasing(bool);
|
void setAntialiasing(bool);
|
||||||
void setTwoSideRender(bool);
|
void setTwoSideRender(bool);
|
||||||
void setGlobalIllum(bool);
|
void setGlobalIllum(bool);
|
||||||
|
static Scene *current;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !SCENE_H_
|
#endif // !SCENE_H_
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue