aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2021-01-14 00:56:57 +0100
committerJulian T <julian@jtle.dk>2021-01-14 00:56:57 +0100
commit57c2f9241543a7d18eab98077530730d49ee10c2 (patch)
tree9dcb819f6c89621f214346a3cbbc88762d05d831
parent8251be3e7ec0e381391c951fd4c8f1ab8080bef9 (diff)
Replace color with pbr-book inspired Spectrum class
-rw-r--r--CMakeLists.txt1
-rw-r--r--app/main.cpp11
-rw-r--r--app/rendercoord.cpp14
-rw-r--r--src/core/common.hpp4
-rw-r--r--src/core/spectrum.cpp90
-rw-r--r--src/core/spectrum.hpp29
-rw-r--r--src/object.cpp16
-rw-r--r--src/object.hpp26
-rw-r--r--src/render.cpp12
-rw-r--r--src/render.hpp4
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.