diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | app/main.cpp | 11 | ||||
-rw-r--r-- | app/rendercoord.cpp | 14 | ||||
-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 |
10 files changed, 155 insertions, 52 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ae5197..941f07b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ FILE(GLOB app_sources ${CMAKE_SOURCE_DIR}/app/*.cpp) SET(sources src/core/ray.cpp src/core/vector.cpp + src/core/spectrum.cpp src/object.cpp src/render.cpp src/scene.cpp diff --git a/app/main.cpp b/app/main.cpp index ebb0536..0455ba7 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -4,6 +4,7 @@ #include "mainwindow.hpp" #include <core/vector.hpp> +#include <core/spectrum.hpp> #include <scene.hpp> #include <render.hpp> #include <object.hpp> @@ -23,11 +24,11 @@ int main(int argc, char *argv[]) conf.m_workers = 4; - Material blue(Color(0.3, 0.3, 1), 1); - Material green(Color(0.3, 1, 0.3), 0, 1, 50); - Material red(Color(1, 0.3, 0.3), 1); - Material white(Color(1, 1, 1), 1); - Material em(Color(1, 1, 1), 0, 0, 0, 2); + Material blue(Spectrum::FromRGB(0.3, 0.3, 1), 1); + Material green(Spectrum::FromRGB(0.3, 1, 0.3), 0, 1, 50); + Material red(Spectrum::FromRGB(1, 0.3, 0.3), 1); + Material white(Spectrum::FromRGB(1, 1, 1), 1); + Material em(Spectrum::FromRGB(1, 1, 1), 0, 0, 0, 2); scn.addShape(new Sphere(red, Vec3d(2, 6, -1), 1)); scn.addShape(new Sphere(green, Vec3d(0, 4, -1), 1.3)); diff --git a/app/rendercoord.cpp b/app/rendercoord.cpp index 00a6437..4abc5d0 100644 --- a/app/rendercoord.cpp +++ b/app/rendercoord.cpp @@ -8,13 +8,13 @@ #include <render.hpp> #include <sstream> -uint32_t colorToUint32(const Color &c) { - Color cnew = Color(c); - cnew.clamp(); +uint32_t colorToUint32(const Spectrum &c) { + Spectrum cnew = c.clamp(0, 1); + cnew *= 255; return (0xFF << 24) + - (cnew.r() << 16) + - (cnew.g() << 8) + - cnew.b(); + ((int)cnew.R() << 16) + + ((int)cnew.G() << 8) + + cnew.B(); } // Run by main thread @@ -36,7 +36,7 @@ void RenderThread::run() { m_work.acquire(); // Very expensive, but necesary to get live rendering - Color *sum = new Color[m_render.m_width * m_render.m_height]; + Spectrum *sum = new Spectrum[m_render.m_width * m_render.m_height]; m_current_samples = 0; 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. |