mirror of
https://github.com/vonhyou/ray-tracer-comp371.git
synced 2025-06-07 23:12:00 +00:00
add dummy global illum
This commit is contained in:
parent
bb70580274
commit
5cf306cbbe
4 changed files with 84 additions and 22 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue