mirror of
https://github.com/vonhyou/ray-tracer-comp371.git
synced 2025-06-08 07:22:01 +00:00
commit
7d7ff991cb
6 changed files with 420 additions and 52 deletions
365
assets/cornell_box_demo.json
Normal file
365
assets/cornell_box_demo.json
Normal file
|
@ -0,0 +1,365 @@
|
|||
{
|
||||
"geometry": [
|
||||
{
|
||||
"comment": "back_wall",
|
||||
"type": "rectangle",
|
||||
"p2": [
|
||||
556,
|
||||
0,
|
||||
-559
|
||||
],
|
||||
"p1": [
|
||||
0,
|
||||
0,
|
||||
-559
|
||||
],
|
||||
"p4": [
|
||||
0,
|
||||
548.8,
|
||||
-559
|
||||
],
|
||||
"p3": [
|
||||
556,
|
||||
548.8,
|
||||
-559
|
||||
],
|
||||
"ac": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"dc": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"sc": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ka": 0,
|
||||
"kd": 0.5,
|
||||
"ks": 0,
|
||||
"pc": 0
|
||||
},
|
||||
{
|
||||
"comment": "right_wall",
|
||||
"type": "rectangle",
|
||||
"p1": [
|
||||
556,
|
||||
0,
|
||||
-559
|
||||
],
|
||||
"p2": [
|
||||
556,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"p3": [
|
||||
556,
|
||||
548.8,
|
||||
0
|
||||
],
|
||||
"p4": [
|
||||
556,
|
||||
548.8,
|
||||
-559
|
||||
],
|
||||
"ac": [
|
||||
1,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"dc": [
|
||||
1,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"sc": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ka": 0,
|
||||
"kd": 0.5,
|
||||
"ks": 0,
|
||||
"pc": 0
|
||||
},
|
||||
{
|
||||
"comment": "left_wall",
|
||||
"type": "rectangle",
|
||||
"p2": [
|
||||
0,
|
||||
0,
|
||||
-559
|
||||
],
|
||||
"p1": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"p4": [
|
||||
0,
|
||||
548.8,
|
||||
0
|
||||
],
|
||||
"p3": [
|
||||
0,
|
||||
548.8,
|
||||
-559
|
||||
],
|
||||
"ac": [
|
||||
0,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"dc": [
|
||||
0,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"sc": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ka": 0,
|
||||
"kd": 0.5,
|
||||
"ks": 0,
|
||||
"pc": 0
|
||||
},
|
||||
{
|
||||
"comment": "ceiling",
|
||||
"type": "rectangle",
|
||||
"p1": [
|
||||
0,
|
||||
548.8,
|
||||
0
|
||||
],
|
||||
"p2": [
|
||||
0,
|
||||
548.8,
|
||||
-559
|
||||
],
|
||||
"p3": [
|
||||
556,
|
||||
548.8,
|
||||
-559.0
|
||||
],
|
||||
"p4": [
|
||||
556,
|
||||
548.8,
|
||||
0
|
||||
],
|
||||
"ac": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"dc": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"sc": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ka": 0,
|
||||
"kd": 1,
|
||||
"ks": 0,
|
||||
"pc": 0
|
||||
},
|
||||
{
|
||||
"comment": "floor",
|
||||
"type": "rectangle",
|
||||
"p1": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"p4": [
|
||||
0,
|
||||
0,
|
||||
-559
|
||||
],
|
||||
"p3": [
|
||||
556,
|
||||
0,
|
||||
-559.0
|
||||
],
|
||||
"p2": [
|
||||
556,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ac": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"dc": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"sc": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ka": 0,
|
||||
"kd": 0.5,
|
||||
"ks": 0,
|
||||
"pc": 0
|
||||
},
|
||||
{
|
||||
"type": "sphere",
|
||||
"centre": [
|
||||
300,
|
||||
228,
|
||||
-228
|
||||
],
|
||||
"radius": 80,
|
||||
"ac": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"dc": [
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"sc": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"ka": 0,
|
||||
"kd": 1,
|
||||
"ks": 1,
|
||||
"pc": 100
|
||||
},
|
||||
{
|
||||
"type": "sphere",
|
||||
"centre": [
|
||||
140,
|
||||
228,
|
||||
-228
|
||||
],
|
||||
"radius": 80,
|
||||
"ac": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"dc": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"sc": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"ka": 0,
|
||||
"kd": 1,
|
||||
"ks": 1,
|
||||
"pc": 100
|
||||
},
|
||||
{
|
||||
"type": "sphere",
|
||||
"centre": [
|
||||
460,
|
||||
228,
|
||||
-228
|
||||
],
|
||||
"radius": 80,
|
||||
"ac": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"dc": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"sc": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"ka": 0,
|
||||
"kd": 1,
|
||||
"ks": 1,
|
||||
"pc": 100
|
||||
}
|
||||
],
|
||||
"light": [
|
||||
{
|
||||
"type": "point",
|
||||
"centre": [
|
||||
278,
|
||||
540,
|
||||
-279.5
|
||||
],
|
||||
"id": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"is": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
}
|
||||
],
|
||||
"output": [
|
||||
{
|
||||
"filename": "cornell_box_demo.ppm",
|
||||
"size": [
|
||||
500,
|
||||
500
|
||||
],
|
||||
"lookat": [
|
||||
0,
|
||||
0,
|
||||
-1
|
||||
],
|
||||
"up": [
|
||||
0,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"fov": 40,
|
||||
"centre": [
|
||||
278,
|
||||
273,
|
||||
800
|
||||
],
|
||||
"ai": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"bkc": [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5
|
||||
],
|
||||
"globalillum": true,
|
||||
"raysperpixel": [
|
||||
10,
|
||||
10
|
||||
],
|
||||
"maxbounces": 3,
|
||||
"probterminate": 0.3333
|
||||
}
|
||||
]
|
||||
}
|
|
@ -39,8 +39,8 @@ Scene *Parser::getScene(const nlohmann::json &j) {
|
|||
sc->setAntialiasing(j.value("antialiasing", false));
|
||||
sc->setTwoSideRender(j.value("twosiderender", false));
|
||||
sc->setGlobalIllum(j.value("globalillum", false));
|
||||
sc->setMaxBounce(j.value("maxbounce", 3));
|
||||
sc->setProbTerminate(j.value("probTerminate", 0.33f));
|
||||
sc->setMaxBounce(j.value("maxbounces", 3));
|
||||
sc->setProbTerminate(j.value("probterminate", 0.33f));
|
||||
if (j.contains("raysperpixel"))
|
||||
sc->setRaysPerPixel(getRpp(j["raysperpixel"]));
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ using Eigen::VectorXi;
|
|||
using std::priority_queue;
|
||||
|
||||
// help function declarations
|
||||
Ray getRay(int, int);
|
||||
Ray getRay(int, int, int, int);
|
||||
void writeColor(int, const Vector3f &);
|
||||
utils::Optional<Vector3f> trace(Ray r);
|
||||
|
@ -27,6 +26,7 @@ Vector3f clamp(const Vector3f &);
|
|||
namespace camera {
|
||||
int width, height, gridWidth, gridHeight, raysPerPixel;
|
||||
Vector3f pos, u, v, du, dv, vpUpperLeft, pxUpperLeft, gdu, gdv;
|
||||
bool globalIllum, antiAliasing;
|
||||
|
||||
void init();
|
||||
} // namespace camera
|
||||
|
@ -91,39 +91,27 @@ void RayTracer::render() {
|
|||
for (int x = 0; x < width; ++x) {
|
||||
Vector3f color = Scene::current->backgroundColor();
|
||||
|
||||
if (Scene::current->globalIllum()) {
|
||||
int success = 0;
|
||||
Vector3f accumulate = Vector3f::Zero();
|
||||
for (int j = 0; j < gridHeight; ++j)
|
||||
for (int i = 0; i < gridWidth; ++i) {
|
||||
|
||||
if (x != width / 2 || y != height / 2 || i || j)
|
||||
; // goto DEBUG_COLOR;
|
||||
Ray ray = getRay(x, y, i, j);
|
||||
for (int rayNum = 0; rayNum < raysPerPixel; ++rayNum) {
|
||||
utils::Optional<Vector3f> result = trace(ray);
|
||||
Ray ray = getRay(x, y, i, j);
|
||||
Optional<Vector3f> result = trace(ray);
|
||||
if (result.hasValue()) {
|
||||
accumulate += result.value();
|
||||
success++;
|
||||
}
|
||||
}
|
||||
|
||||
// std::cout << accumulate.transpose() << " (" << success <<
|
||||
// std::endl;
|
||||
}
|
||||
|
||||
if (success)
|
||||
if (success) {
|
||||
if (globalIllum)
|
||||
color = gammaCorrection(accumulate / success, 1.0f / 2.1f);
|
||||
} else {
|
||||
Ray ray = getRay(x, y);
|
||||
Optional<HitRecord> hitRecord = getHitRecord(ray);
|
||||
else
|
||||
color = accumulate / success;
|
||||
}
|
||||
|
||||
if (hitRecord.hasValue()) {
|
||||
HitRecord hit = hitRecord.value();
|
||||
color = calculateColor(hit, y * width + x);
|
||||
}
|
||||
}
|
||||
DEBUG_COLOR:
|
||||
writeColor(y * width + x, clamp(color));
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +121,7 @@ void RayTracer::render() {
|
|||
/**
|
||||
* Calculate color using phong model
|
||||
*/
|
||||
Vector3f RayTracer::calculateColor(const HitRecord &hit, int i) const {
|
||||
Vector3f RayTracer::calculateColor(const HitRecord &hit) const {
|
||||
Vector3f result(0, 0, 0);
|
||||
for (auto light : lights)
|
||||
result += light->isUse() ? light->illumination(hit, geometries)
|
||||
|
@ -173,14 +161,22 @@ Light *RayTracer::singleLightSource() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Ray getRay(int x, int y) {
|
||||
using namespace camera;
|
||||
return Ray(pos, pxUpperLeft + x * du + y * dv - pos);
|
||||
// This should generate a higher quality random number
|
||||
float getRandomNumber() {
|
||||
static std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
||||
static std::mt19937 generator;
|
||||
return distribution(generator);
|
||||
}
|
||||
|
||||
Ray getRay(int x, int y, int i, int j) {
|
||||
using namespace camera;
|
||||
return Ray(pos, vpUpperLeft + x * du + i * gdu + y * dv + j * gdv - pos);
|
||||
Vector3f offset = Vector3f::Zero();
|
||||
|
||||
if (globalIllum || antiAliasing)
|
||||
offset = getRandomNumber() * gdu + getRandomNumber() * gdv;
|
||||
|
||||
return Ray(pos,
|
||||
vpUpperLeft + x * du + i * gdu + y * dv + j * gdv + offset - pos);
|
||||
}
|
||||
|
||||
Vector3f clamp(const Vector3f &color) {
|
||||
|
@ -193,13 +189,6 @@ void writeColor(int i, const Vector3f &color) {
|
|||
Output::current->b(i, color.z());
|
||||
}
|
||||
|
||||
// This should generate a higher quality random number
|
||||
float getRandomNumber() {
|
||||
static std::uniform_real_distribution<float> distribution(0.0, 1.0);
|
||||
static std::mt19937 generator;
|
||||
return distribution(generator);
|
||||
}
|
||||
|
||||
// Generate a randon point on a unit hemisphere
|
||||
Vector3f getRandomDirection() {
|
||||
RETRY_RANDOM:
|
||||
|
@ -268,17 +257,23 @@ RETRY_TRACING:
|
|||
std::max(0.0f, hit.normal().dot(direction));
|
||||
}
|
||||
|
||||
utils::Optional<Vector3f> RayTracer::trace(Ray r) const {
|
||||
Optional<Vector3f> RayTracer::trace(Ray r) const {
|
||||
Optional<HitRecord> hitRecord = getHitRecord(r);
|
||||
if (!camera::globalIllum) {
|
||||
if (hitRecord.hasValue())
|
||||
return Optional<Vector3f>(calculateColor(hitRecord.value()));
|
||||
else if (camera::antiAliasing)
|
||||
return Optional<Vector3f>(Scene::current->backgroundColor());
|
||||
} else {
|
||||
if (hitRecord.hasValue()) {
|
||||
Vector3f color = trace(hitRecord.value(), Scene::current->maxBounce(),
|
||||
Scene::current->probTerminate());
|
||||
|
||||
if (color != Vector3f::Zero())
|
||||
return utils::Optional<Vector3f>(color);
|
||||
return Optional<Vector3f>(color);
|
||||
}
|
||||
}
|
||||
|
||||
return utils::Optional<Vector3f>::nullopt;
|
||||
return Optional<Vector3f>::nullopt;
|
||||
}
|
||||
|
||||
namespace camera {
|
||||
|
@ -314,7 +309,12 @@ void init() {
|
|||
vpUpperLeft = pos + lookAt - u / 2.0 - v / 2.0;
|
||||
pxUpperLeft = vpUpperLeft + (du + dv) / 2.0;
|
||||
|
||||
VectorXi data = Scene::current->raysPerPixel();
|
||||
globalIllum = Scene::current->globalIllum();
|
||||
antiAliasing = Scene::current->antiAliasing();
|
||||
|
||||
VectorXi data = !(globalIllum || antiAliasing)
|
||||
? VectorXi(1)
|
||||
: Scene::current->raysPerPixel();
|
||||
gridWidth = getGridWidth(data);
|
||||
gridHeight = getGridHeight(data);
|
||||
raysPerPixel = getRayNumber(data);
|
||||
|
|
|
@ -28,7 +28,7 @@ private:
|
|||
void render();
|
||||
Optional<HitRecord> getHitRecord(Ray, const Geometry *) const;
|
||||
Optional<HitRecord> getHitRecord(Ray) const;
|
||||
Vector3f calculateColor(const HitRecord &, int) const;
|
||||
Vector3f calculateColor(const HitRecord &) const;
|
||||
Light *singleLightSource() const;
|
||||
Optional<Vector3f> trace(Ray) const;
|
||||
Vector3f trace(HitRecord, int, float) const;
|
||||
|
|
|
@ -12,6 +12,8 @@ float Scene::fov() { return fov_; }
|
|||
|
||||
bool Scene::globalIllum() { return globalIllum_; }
|
||||
|
||||
bool Scene::antiAliasing() { return antialiasing_; }
|
||||
|
||||
int Scene::maxBounce() { return maxBounce_; }
|
||||
|
||||
float Scene::probTerminate() { return probTerminate_; }
|
||||
|
|
|
@ -41,6 +41,7 @@ public:
|
|||
int height();
|
||||
float fov();
|
||||
bool globalIllum();
|
||||
bool antiAliasing();
|
||||
int maxBounce();
|
||||
float probTerminate();
|
||||
Vector3f ai() const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue