aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2021-01-24 18:13:44 +0100
committerJulian T <julian@jtle.dk>2021-01-24 18:22:11 +0100
commit41ea2d8f94043d49fc26aaaa8030a73dcfdc2da9 (patch)
treefcc07052425c65b38c1724f4fc30299a1cb48716 /src
parenta38e6014ea5441e9d29fcb3b5607cd94e4061cff (diff)
Create rust project
Diffstat (limited to 'src')
-rw-r--r--src/common.hpp6
-rw-r--r--src/main.rs3
-rw-r--r--src/object.cpp103
-rw-r--r--src/object.hpp76
-rw-r--r--src/ray.cpp17
-rw-r--r--src/ray.hpp15
-rw-r--r--src/render.cpp166
-rw-r--r--src/render.hpp61
-rw-r--r--src/scene.cpp5
-rw-r--r--src/scene.hpp15
-rw-r--r--src/vector.cpp106
-rw-r--r--src/vector.hpp33
12 files changed, 3 insertions, 603 deletions
diff --git a/src/common.hpp b/src/common.hpp
deleted file mode 100644
index fd219bf..0000000
--- a/src/common.hpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef COMMON_H
-#define COMMON_H
-
-#define ZERO_APPROX 1e-6
-
-#endif
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..e7a11a9
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("Hello, world!");
+}
diff --git a/src/object.cpp b/src/object.cpp
deleted file mode 100644
index 1449cbb..0000000
--- a/src/object.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "object.hpp"
-
-#include <math.h>
-#include <iostream>
-#include "common.hpp"
-
-void Color::clamp() {
- if (m_x > 1) { m_x = 1; }
- if (m_y > 1) { m_y = 1; }
- if (m_z > 1) { m_z = 1; }
-}
-
-Material::Material(Color color, double defuse, double emissive) {
- m_color = color;
- m_defuse = defuse;
- m_emissive = emissive;
-}
-
-Color Material::reflect(const Vec3d &normal, const Vec3d &in, const Vec3d &out, const Color &incol) const {
- return Vec3d(m_color) * m_emissive +
- (Vec3d(m_color) * Vec3d(incol)) * (out.dot(normal) * m_defuse);
-}
-
-Sphere::Sphere(const Material &mat, Vec3d center, double radius) : Shape(mat) {
- m_center = center;
- m_radius = radius;
-}
-
-Plane::Plane(const Material &mat, Vec3d start, Vec3d norm) : Shape(mat) {
- m_start = start;
- m_norm = norm;
-
- m_norm.normalize();
-}
-
-Vec3d Sphere::norm_at(const Vec3d &point, const Vec3d&) const {
- auto res = point - m_center;
- res.normalize();
- return res;
-}
-
-// https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
-double Sphere::intersect(const Ray &ray, bool skip_dist) const {
- // Calculate O - C used multiple places
- auto oc = ray.m_start - m_center;
- // Calculate components of quadratic formula
- // a = 1 when ray.direction is a unit vector
- auto a = 1;
- auto b = 2 * ray.m_direction.dot(oc);
- auto c = oc.dot(oc) - m_radius * m_radius;
-
- // Solve quadratic function
- auto discr = b * b - 4 * a * c;
- if (discr < 0) {
- // No solution
- return -1;
- }
- if (skip_dist) {
- // Do not calculate distance
- return 1;
- }
-
- auto q = (b > 0) ?
- -0.5 * (b + sqrt(discr)):
- -0.5 * (b - sqrt(discr));
- auto t1 = q; // Assuming a = 1
- auto t0 = c / q;
-
- // Find correct result
- if (t0 <= ZERO_APPROX) {
- t0 = t1;
- }
-
- if (t0 <= ZERO_APPROX) {
- return -1;
- }
-
- return t0;
-}
-
-Vec3d Plane::norm_at(const Vec3d&, const Vec3d &indir) const {
- auto scale = m_norm.dot(indir);
- return scale > 0 ? -m_norm : m_norm;
-}
-
-// https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-plane-and-ray-disk-intersection
-// Requires that vectors are normalized
-// Skip dist is ignored as distance must be calculated
-double Plane::intersect(const Ray &ray, bool) const {
- // If ray is parallel
- auto nr = m_norm.dot(ray.m_direction);
- if (abs(nr) < ZERO_APPROX) {
- return -1;
- }
-
- // Calculate distance
- auto dist = m_norm.dot(m_start - ray.m_start) / nr;
- if (dist < 0) {
- return -1;
- }
-
- return dist;
-}
diff --git a/src/object.hpp b/src/object.hpp
deleted file mode 100644
index e697ba2..0000000
--- a/src/object.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef OBJECT_H
-#define OBJECT_H
-
-#include <memory>
-#include "vector.hpp"
-#include "ray.hpp"
-
-class Color : public Vec3d {
- public:
- Color() {}
- Color(const Vec3d &v) : Vec3d(v) {}
- Color(double r, double g, double b) : Vec3d(r, g, b) {}
-
- uint8_t r() { return m_x * 255; }
- uint8_t g() { return m_y * 255; }
- uint8_t b() { return m_z * 255; }
-
- Color& operator+=(const Color& op) {
- Vec3d::operator+=(op);
- return *this;
- }
- void clamp();
-};
-
-// Implements phong BRDF
-class Material {
- public:
- Material(Color color, double defuse, double emissive=0);
-
- Color reflect(const Vec3d &normal, const Vec3d &in, const Vec3d &out, const Color &incol) const;
-
- Color emits() const {
- return m_color * m_emissive;
- }
-
- // Whether the material is reflective
- bool reflects() const { return m_defuse > 0; }
- private:
- Color m_color;
- double m_defuse;
- double m_emissive;
-};
-
-class Shape {
- public:
- Shape(const Material &mat) : m_mat(mat) { }
-
- virtual Vec3d norm_at(const Vec3d &point, const Vec3d &indir) const = 0;
- virtual double intersect(const Ray &ray, bool skip_dist) const = 0;
-
- const Material &m_mat;
-};
-
-class Sphere : public Shape {
- public:
- Sphere(const Material &mat, Vec3d center, double radius);
- Vec3d norm_at(const Vec3d &point, const Vec3d &indir) const;
- double intersect(const Ray &ray, bool skip_dist) const;
-
- private:
- Vec3d m_center;
- double m_radius;
-};
-
-class Plane : public Shape {
- public:
- Plane(const Material &mat, Vec3d start, Vec3d norm);
- Vec3d norm_at(const Vec3d &point, const Vec3d &indir) const;
- double intersect(const Ray &ray, bool skip_dist) const;
-
- private:
- Vec3d m_start;
- Vec3d m_norm;
-};
-
-#endif
diff --git a/src/ray.cpp b/src/ray.cpp
deleted file mode 100644
index 7bc6201..0000000
--- a/src/ray.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "ray.hpp"
-
-Ray::Ray(Vec3d start, Vec3d direction, bool normalize) {
- m_start = start;
- m_direction = direction;
-
- if (normalize) {
- m_direction.normalize();
- }
-}
-
-Ray::Ray(Vec3d a, Vec3d b) {
- m_start = a;
- m_direction = b - a;
-
- m_direction.normalize();
-}
diff --git a/src/ray.hpp b/src/ray.hpp
deleted file mode 100644
index 6341d44..0000000
--- a/src/ray.hpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef RAY_H
-#define RAY_H
-
-#include "vector.hpp"
-
-class Ray {
- public:
- Ray(Vec3d start, Vec3d direction, bool normalize);
- Ray(Vec3d a, Vec3d b);
-
- Vec3d m_start;
- Vec3d m_direction;
-};
-
-#endif
diff --git a/src/render.cpp b/src/render.cpp
deleted file mode 100644
index c278797..0000000
--- a/src/render.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-#include "render.hpp"
-#include "vector.hpp"
-#include "common.hpp"
-
-#include <cstdlib>
-#include <math.h>
-#include <iostream>
-
-#define FOV 1.74533
-
-// Uniform sampling
-#define SAMPLING_POWER 0
-
-const Vec3d up = Vec3d(0, 1, 0);
-
-void Random::seed(unsigned seed) {
- for (unsigned i = 0; i < seed; i++) {
- rand_r(&m_seed);
- }
-}
-
-double Random::operator()() {
- return (double)rand_r(&m_seed) / (double)RAND_MAX;
-}
-
-Sampler::Sampler(Random &src) : m_src(src) { }
-
-Vec3d Sampler::sample(const Vec3d &norm) {
- /*
- auto theta = asin(pow(1 - random(), (double)1 / (1 + SAMPLING_POWER)));
- auto phi = 2 * M_PI * random();
- */
-
- auto theta = 2.0 * M_PI * m_src();
- auto phi = acos(2.0 * m_src() - 1.0);
-
- auto sinphi = sin(phi);
-
- auto newvec = Vec3d(cos(theta) * sinphi, sin(theta) * sinphi, cos(phi));
-
- if (newvec.dot(norm) <= 0) {
- newvec = -newvec;
- }
-
- return newvec;
-}
-
-Renderer::Renderer(const Scene &scn, Vec3d eye, Vec3d target, unsigned width, unsigned height, unsigned maxhops) :
- m_sampler(m_random),
- m_scn(scn)
-{
- m_eye = eye;
- m_target = target;
- m_width = width;
- m_height = height;
- m_maxhops = maxhops;
-
- recalculate();
-}
-
-void Renderer::recalculate() {
- auto tmp = m_target - m_eye;
-
- // Orthogonal vector to E
- auto b = up.cross(tmp);
-
- b.normalize();
- tmp.normalize();
-
- auto v = tmp.cross(b);
-
- // Calculate size of viewplane
- double gx = tan( FOV / 2);
- double gy = gx * ((double) m_height / m_width);
-
- // Calculate scaling vectors
- m_qx = b * ((2 * gx) / (m_width - 1));
- m_qy = v * ((2 * gy) / (m_height - 1));
-
- // Calculate starting point
- m_blc = tmp - (b * gx) - (v * gy);
-}
-
-Ray Renderer::findray(double x, double y) const {
- auto dir = m_blc + (m_qx * x) + (m_qy * y);
- return Ray(m_eye, dir, true);
-}
-
-Color Renderer::render(unsigned x, unsigned y, unsigned samples) {
-
- Color sum(0, 0, 0);
-
- for (unsigned i = 0; i < samples; i++) {
- auto r = findray(x + m_random(), y + m_random());
- sum += pathtrace_sample(r, 0);
- }
-
- if (samples < 2) {
- return sum;
- } else {
- return Vec3d(sum) / (double)samples;
- }
-}
-
-Color Renderer::pathtrace_sample(const Ray &r, unsigned hop) {
- if (hop >= m_maxhops) {
- return Color(0, 0, 0);
- }
-
- double dist;
- auto res = cast_ray(r, 0, &dist);
-
- if (!res) {
- return Color(0, 0, 0);
- }
-
- auto col = res->m_mat.emits();
- if (res->m_mat.reflects()) {
- // Calculate endpoint
- auto end = r.m_start + r.m_direction * dist;
- auto norm = res->norm_at(end, r.m_direction);
-
- auto randdir = m_sampler.sample(norm);
- auto newray = Ray(end, randdir, true);
- auto incol = pathtrace_sample(newray, hop+1);
-
- col += res->m_mat.reflect(norm, r.m_direction, newray.m_direction, incol);
- }
-
- return col;
-}
-
-const Shape* Renderer::cast_ray(const Ray &r, double chk_dist, double *dist_ret) {
- const Shape *smallest = nullptr;
- double dist = 0;
-
- for (auto obj : m_scn.objs) {
- if (!obj) {
- continue;
- }
- auto d = obj->intersect(r, false);
- if (d > ZERO_APPROX) {
- if (chk_dist > 0 && d < chk_dist) {
- dist = d; smallest = obj;
- goto exit;
- }
- if (d < dist || smallest == nullptr) {
- dist = d; smallest = obj;
- }
- }
- }
-
- if (chk_dist > 0) {
- // If we reach this it means none of the
- // object where within distance.
- return nullptr;
- }
-
-exit:
-
- if (dist_ret) {
- *dist_ret = dist;
- }
-
- return smallest;
-}
diff --git a/src/render.hpp b/src/render.hpp
deleted file mode 100644
index 7557fce..0000000
--- a/src/render.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef RENDER_H
-#define RENDER_H
-
-#include "vector.hpp"
-#include "ray.hpp"
-#include "scene.hpp"
-
-class Random {
- public:
- void seed(unsigned seed);
- double operator()();
-
- private:
- unsigned m_seed;
-};
-
-// Samples a random direction in a hemisphere, cosine weighed
-// https://blog.thomaspoulet.fr/uniform-sampling-on-unit-hemisphere/
-class Sampler {
- public:
- Sampler(Random &src);
-
- Vec3d sample(const Vec3d &norm);
-
- private:
- Random &m_src;
-};
-
-class Renderer {
- public:
- Renderer(const Scene &scn, Vec3d eye, Vec3d target, unsigned width, unsigned height, unsigned maxhops);
-
- Color render(unsigned x, unsigned y, unsigned samples);
-
- unsigned m_width, m_height;
- Sampler m_sampler;
-
- private:
- void recalculate();
- Ray findray(double x, double y) const ;
-
- Color pathtrace_sample(const Ray &r, unsigned hop);
- // Will return first result less than chk_dist.
- // This is ignored if chk_dist is 0.
- // If dist is non-null the resulting distance is written here.
- const Shape* cast_ray(const Ray &r, double chk_dist, double *dist);
-
- const Scene &m_scn;
-
- Random m_random;
-
- // User options
- Vec3d m_eye, m_target;
- unsigned m_maxhops;
-
- // Calculated values
- Vec3d m_qx, m_qy, m_blc;
-
-};
-
-#endif
diff --git a/src/scene.cpp b/src/scene.cpp
deleted file mode 100644
index a8c0695..0000000
--- a/src/scene.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "scene.hpp"
-
-void Scene::addShape(const Shape *obj) {
- objs.push_back(obj);
-}
diff --git a/src/scene.hpp b/src/scene.hpp
deleted file mode 100644
index f270409..0000000
--- a/src/scene.hpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef SCENE_H
-#define SCENE_H
-
-#include <vector>
-#include "object.hpp"
-
-class Scene {
- public:
- void addShape(const Shape *obj);
-
- std::vector<const Shape*> objs;
-
-};
-
-#endif
diff --git a/src/vector.cpp b/src/vector.cpp
deleted file mode 100644
index 51d8e2e..0000000
--- a/src/vector.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-#include "vector.hpp"
-
-#include <math.h>
-#include <stdexcept>
-
-Vec3d::Vec3d() {
- set(0, 0, 0);
-}
-
-Vec3d::Vec3d(double x, double y, double z) {
- set(x, y, z);
-}
-
-void Vec3d::set(double x, double y, double z) {
- m_x = x;
- m_y = y;
- m_z = z;
-}
-
-void Vec3d::normalize() {
- auto len = length();
- if (len == 0) {
- throw std::runtime_error("Normalizing zero vector");
- }
-
- m_x /= len;
- m_y /= len;
- m_z /= len;
-}
-
-double Vec3d::length() const {
- return sqrt(m_x * m_x + m_y * m_y + m_z * m_z);
-}
-
-double Vec3d::dot(const Vec3d &vec) const {
- return m_x * vec.m_x + m_y * vec.m_y + m_z * vec.m_z;
-}
-
-Vec3d Vec3d::cross(const Vec3d &vec) const {
- return Vec3d(
- m_y * vec.m_z - m_z * vec.m_y,
- m_z * vec.m_x - m_x * vec.m_z,
- m_x * vec.m_y - m_y * vec.m_x
- );
-}
-
-Vec3d Vec3d::operator+(const Vec3d &vec) const {
- return Vec3d(
- m_x + vec.m_x,
- m_y + vec.m_y,
- m_z + vec.m_z
- );
-}
-
-Vec3d& Vec3d::operator+=(const Vec3d &vec) {
- m_x += vec.m_x;
- m_y += vec.m_y;
- m_z += vec.m_z;
- return *this;
-}
-
-Vec3d Vec3d::operator-(const Vec3d &vec) const {
- return Vec3d(
- m_x - vec.m_x,
- m_y - vec.m_y,
- m_z - vec.m_z
- );
-}
-
-Vec3d Vec3d::operator-() const {
- return Vec3d(
- -m_x,
- -m_y,
- -m_z
- );
-}
-
-
-Vec3d Vec3d::operator*(double op) const {
- return Vec3d(
- m_x * op,
- m_y * op,
- m_z * op
- );
-}
-
-Vec3d Vec3d::operator*(const Vec3d &vec) const {
- return Vec3d(
- m_x * vec.m_x,
- m_y * vec.m_y,
- m_z * vec.m_z
- );
-}
-
-Vec3d Vec3d::operator/(double op) const {
- return Vec3d(
- m_x / op,
- m_y / op,
- m_z / op
- );
-}
-
-std::ostream& operator<<(std::ostream &out, const Vec3d &v){
- out << "[ " << v.m_x << ", " << v.m_y << ", " << v.m_z << " ]";
- return out;
-}
diff --git a/src/vector.hpp b/src/vector.hpp
deleted file mode 100644
index 20e8210..0000000
--- a/src/vector.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef VECTOR_H
-#define VECTOR_H
-
-#include <iostream>
-
-class Vec3d {
- public:
- Vec3d();
- Vec3d(double x, double y, double z);
-
- void set(double x, double y, double z);
- void normalize();
-
- double length() const;
- double dot(const Vec3d &vec) const;
-
- Vec3d cross(const Vec3d &vec) const;
-
- // Operators
- Vec3d operator+(const Vec3d &vec) const;
- Vec3d& operator+=(const Vec3d &vec);
- Vec3d operator-(const Vec3d &vec) const;
- Vec3d operator-() const;
- Vec3d operator*(double) const;
- Vec3d operator*(const Vec3d &vec) const;
- Vec3d operator/(double) const;
-
- friend std::ostream& operator<<(std::ostream& os, const Vec3d &v);
-
- double m_x, m_y, m_z;
-};
-
-#endif