diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/common.hpp | 4 | ||||
-rw-r--r-- | src/core/spectrum.cpp | 90 | ||||
-rw-r--r-- | src/core/spectrum.hpp | 29 | ||||
-rw-r--r-- | src/object.cpp | 16 | ||||
-rw-r--r-- | src/object.hpp | 26 | ||||
-rw-r--r-- | src/render.cpp | 12 | ||||
-rw-r--r-- | src/render.hpp | 4 |
7 files changed, 141 insertions, 40 deletions
diff --git a/src/core/common.hpp b/src/core/common.hpp index fd219bf..a3e682e 100644 --- a/src/core/common.hpp +++ b/src/core/common.hpp @@ -1,6 +1,10 @@ #ifndef COMMON_H #define COMMON_H +#include <limits> + #define ZERO_APPROX 1e-6 +#define INFINITY std::numeric_limits<double>::infinity() + #endif diff --git a/src/core/spectrum.cpp b/src/core/spectrum.cpp new file mode 100644 index 0000000..d53cf49 --- /dev/null +++ b/src/core/spectrum.cpp @@ -0,0 +1,90 @@ +#include "spectrum.hpp" + +static double clamp(double v, double low = 0, double high = 0) { + if (v < low) { + return low; + } + if (v > high) { + return high; + } + return v; +} + +Spectrum::Spectrum(double v) { + c[0] = v; + c[1] = v; + c[2] = v; +} + +Spectrum Spectrum::FromRGB(double r, double g, double b) { + Spectrum ret; + ret.c[0] = r; + ret.c[1] = g; + ret.c[2] = b; + + return ret; +} + +Spectrum &Spectrum::operator+=(const Spectrum &o) { + c[0] += o.c[0]; + c[1] += o.c[1]; + c[2] += o.c[2]; + + return *this; +} + +Spectrum &Spectrum::operator*=(double o) { + c[0] *= o; + c[1] *= o; + c[2] *= o; + + return *this; +} + +Spectrum Spectrum::operator+(const Spectrum &o) const { + Spectrum ret = *this; + + ret.c[0] += o.c[0]; + ret.c[1] += o.c[1]; + ret.c[2] += o.c[2]; + + return ret; +} + +Spectrum Spectrum::operator-(const Spectrum &o) const { + Spectrum ret = *this; + + ret.c[0] -= o.c[0]; + ret.c[1] -= o.c[1]; + ret.c[2] -= o.c[2]; + + return ret; +} + +Spectrum Spectrum::operator*(const Spectrum &o) const { + Spectrum ret = *this; + + ret.c[0] *= o.c[0]; + ret.c[1] *= o.c[1]; + ret.c[2] *= o.c[2]; + + return ret; +} + +Spectrum Spectrum::operator/(const Spectrum &o) const { + Spectrum ret = *this; + + ret.c[0] /= o.c[0]; + ret.c[1] /= o.c[1]; + ret.c[2] /= o.c[2]; + + return ret; +} + +Spectrum Spectrum::clamp(double low, double high) const { + Spectrum ret; + ret.c[0] = ::clamp(c[0], low, high); + ret.c[1] = ::clamp(c[1], low, high); + ret.c[2] = ::clamp(c[2], low, high); + return ret; +} diff --git a/src/core/spectrum.hpp b/src/core/spectrum.hpp new file mode 100644 index 0000000..de9355d --- /dev/null +++ b/src/core/spectrum.hpp @@ -0,0 +1,29 @@ +#ifndef SPECTRUM_H +#define SPECTRUM_H + +#include "core/common.hpp" + +// Contains a RGB spectrum value +class Spectrum { +public: + Spectrum(double v = 0); + static Spectrum FromRGB(double r, double g, double b); + + Spectrum &operator+=(const Spectrum &o); + Spectrum &operator*=(double o); + Spectrum operator+(const Spectrum &o) const; + Spectrum operator-(const Spectrum &o) const; + Spectrum operator*(const Spectrum &o) const; + Spectrum operator/(const Spectrum &o) const; + + Spectrum clamp(double low = 0, double high = INFINITY) const; + + double R() const { return c[0]; } + double G() const { return c[1]; } + double B() const { return c[2]; } + +private: + double c[3]; +}; + +#endif diff --git a/src/object.cpp b/src/object.cpp index 0f7332f..40e21b2 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -4,13 +4,7 @@ #include <iostream> #include "core/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 spectral, double spectral_pow, double emissive) { +Material::Material(Spectrum color, double defuse, double spectral, double spectral_pow, double emissive) { m_color = color; m_defuse = defuse; m_emissive = emissive; @@ -18,17 +12,17 @@ Material::Material(Color color, double defuse, double spectral, double spectral_ m_spectral_pow = spectral_pow; } -Color Material::reflect(const Vec3d &normal, const Vec3d &in, const Vec3d &out, const Color &incol) const { +Spectrum Material::reflect(const Vec3d &normal, const Vec3d &in, const Vec3d &out, const Spectrum &incol) const { // Emissive - Color c = Vec3d(m_color) * m_emissive; + Spectrum c = m_color * m_emissive; // Defuse - c += (Vec3d(m_color) * Vec3d(incol)) * (in.dot(normal) * m_defuse); + c += (m_color * incol) * (in.dot(normal) * m_defuse); // Spectral if (m_spectral > 0) { auto R = normal * (2 * normal.dot(in)) - in; - c += Vec3d(incol) * pow(out.dot(R) * m_spectral, m_spectral_pow); + c += incol * pow(out.dot(R) * m_spectral, m_spectral_pow); } return c; diff --git a/src/object.hpp b/src/object.hpp index 1cfb254..1cfd10d 100644 --- a/src/object.hpp +++ b/src/object.hpp @@ -4,39 +4,23 @@ #include <memory> #include "core/vector.hpp" #include "core/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(); -}; +#include "core/spectrum.hpp" // Implements phong BRDF class Material { public: - Material(Color color, double defuse, double spectral=0, double spectral_pow=0, double emissive=0); + Material(Spectrum color, double defuse, double spectral=0, double spectral_pow=0, double emissive=0); - Color reflect(const Vec3d &normal, const Vec3d &in, const Vec3d &out, const Color &incol) const; + Spectrum reflect(const Vec3d &normal, const Vec3d &in, const Vec3d &out, const Spectrum &incol) const; - Color emits() const { + Spectrum emits() const { return m_color * m_emissive; } // Whether the material is reflective bool reflects() const { return m_defuse+m_spectral > 0; } private: - Color m_color; + Spectrum m_color; double m_defuse; double m_emissive; double m_spectral; diff --git a/src/render.cpp b/src/render.cpp index a81c6bb..286cbae 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -86,9 +86,9 @@ Ray Renderer::findray(double x, double y) const { return Ray(m_eye, dir, true); } -Color Renderer::render(unsigned x, unsigned y, unsigned samples) { +Spectrum Renderer::render(unsigned x, unsigned y, unsigned samples) { - Color sum(0, 0, 0); + Spectrum sum; for (unsigned i = 0; i < samples; i++) { auto r = findray(x + m_random(), y + m_random()); @@ -98,20 +98,20 @@ Color Renderer::render(unsigned x, unsigned y, unsigned samples) { if (samples < 2) { return sum; } else { - return Vec3d(sum) / (double)samples; + return sum / (double)samples; } } -Color Renderer::pathtrace_sample(const Ray &r, unsigned hop) { +Spectrum Renderer::pathtrace_sample(const Ray &r, unsigned hop) { if (hop >= m_maxhops) { - return Color(0, 0, 0); + return Spectrum(); } double dist; auto res = cast_ray(r, 0, &dist); if (!res) { - return Color(0, 0, 0); + return Spectrum(); } auto col = res->m_mat.emits(); diff --git a/src/render.hpp b/src/render.hpp index 8102686..f8da98a 100644 --- a/src/render.hpp +++ b/src/render.hpp @@ -30,7 +30,7 @@ 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); + Spectrum render(unsigned x, unsigned y, unsigned samples); unsigned m_width, m_height; Sampler m_sampler; @@ -39,7 +39,7 @@ class Renderer { void recalculate(); Ray findray(double x, double y) const ; - Color pathtrace_sample(const Ray &r, unsigned hop); + Spectrum 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. |