aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/common.hpp2
-rw-r--r--src/core/random.hpp20
-rw-r--r--src/core/spectrum.hpp2
-rw-r--r--src/core/vector.cpp14
-rw-r--r--src/core/vector.hpp17
-rw-r--r--src/render.cpp4
-rw-r--r--src/sampling/random.cpp13
-rw-r--r--src/sampling/random.hpp18
-rw-r--r--src/sampling/sampler.cpp10
-rw-r--r--src/sampling/sampler.hpp52
10 files changed, 147 insertions, 5 deletions
diff --git a/src/core/common.hpp b/src/core/common.hpp
index a3e682e..7965815 100644
--- a/src/core/common.hpp
+++ b/src/core/common.hpp
@@ -5,6 +5,6 @@
#define ZERO_APPROX 1e-6
-#define INFINITY std::numeric_limits<double>::infinity()
+#define INFTY std::numeric_limits<double>::infinity()
#endif
diff --git a/src/core/random.hpp b/src/core/random.hpp
new file mode 100644
index 0000000..bc6a173
--- /dev/null
+++ b/src/core/random.hpp
@@ -0,0 +1,20 @@
+#ifndef RANDOM_H
+#define RANDOM_H
+
+#include <random>
+
+// TODO think more about
+class Random {
+ public:
+ Random(int seed = 0) : m_gen(seed), m_dist(0, 1) {}
+
+ inline double getDouble() {
+ return m_dist(m_gen);
+ };
+
+ private:
+ std::minstd_rand m_gen;
+ std::uniform_real_distribution<double> m_dist;
+};
+
+#endif
diff --git a/src/core/spectrum.hpp b/src/core/spectrum.hpp
index de9355d..2a293fa 100644
--- a/src/core/spectrum.hpp
+++ b/src/core/spectrum.hpp
@@ -16,7 +16,7 @@ public:
Spectrum operator*(const Spectrum &o) const;
Spectrum operator/(const Spectrum &o) const;
- Spectrum clamp(double low = 0, double high = INFINITY) const;
+ Spectrum clamp(double low = 0, double high = INFTY) const;
double R() const { return c[0]; }
double G() const { return c[1]; }
diff --git a/src/core/vector.cpp b/src/core/vector.cpp
index 51d8e2e..c790741 100644
--- a/src/core/vector.cpp
+++ b/src/core/vector.cpp
@@ -1,8 +1,22 @@
#include "vector.hpp"
+#include <cmath>
#include <math.h>
#include <stdexcept>
+Vec2d::Vec2d() {
+ set(0, 0);
+}
+
+Vec2d::Vec2d(double x, double y) {
+ set(x, y);
+}
+
+void Vec2d::set(double x, double y) {
+ m_x = x;
+ m_y = y;
+}
+
Vec3d::Vec3d() {
set(0, 0, 0);
}
diff --git a/src/core/vector.hpp b/src/core/vector.hpp
index 20e8210..adc0bae 100644
--- a/src/core/vector.hpp
+++ b/src/core/vector.hpp
@@ -2,12 +2,29 @@
#define VECTOR_H
#include <iostream>
+#include <math.h>
+
+class Vec2d {
+ public:
+ Vec2d();
+ Vec2d(double x, double y);
+
+ void set(double x, double y);
+
+ double m_x, m_y, m_z;
+};
class Vec3d {
public:
Vec3d();
Vec3d(double x, double y, double z);
+ static inline Vec3d FromSpherical(double sinTheta, double cosTheta, double phi) {
+ return Vec3d(sinTheta * std::cos(phi),
+ sinTheta * std::sin(phi),
+ cosTheta);
+ }
+
void set(double x, double y, double z);
void normalize();
diff --git a/src/render.cpp b/src/render.cpp
index 286cbae..5762af4 100644
--- a/src/render.cpp
+++ b/src/render.cpp
@@ -34,9 +34,7 @@ Vec3d Sampler::sample(const Vec3d &norm) {
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));
+ auto newvec = Vec3d::FromSpherical(sin(theta), cos(theta), phi);
if (newvec.dot(norm) <= 0) {
newvec = -newvec;
diff --git a/src/sampling/random.cpp b/src/sampling/random.cpp
new file mode 100644
index 0000000..d77e78a
--- /dev/null
+++ b/src/sampling/random.cpp
@@ -0,0 +1,13 @@
+#include "random.hpp"
+
+RandomSampler::RandomSampler(long samples, int seed)
+ : Sampler(samples), m_rng(seed) {}
+
+double RandomSampler::getSample() {
+ return m_rng.getDouble();
+}
+
+Vec2d RandomSampler::get2dSample() {
+ return Vec2d(m_rng.getDouble(), m_rng.getDouble());
+}
+
diff --git a/src/sampling/random.hpp b/src/sampling/random.hpp
new file mode 100644
index 0000000..d1acaa8
--- /dev/null
+++ b/src/sampling/random.hpp
@@ -0,0 +1,18 @@
+#ifndef SAMPLER_RANDOM_H
+#define SAMPLER_RANDOM_H
+
+#include "sampler.hpp"
+#include <core/random.hpp>
+
+class RandomSampler : public Sampler {
+ public:
+ RandomSampler(long samples, int seed = 0);
+
+ double getSample();
+ Vec2d get2dSample();
+
+ private:
+ Random m_rng;
+};
+
+#endif
diff --git a/src/sampling/sampler.cpp b/src/sampling/sampler.cpp
new file mode 100644
index 0000000..d960816
--- /dev/null
+++ b/src/sampling/sampler.cpp
@@ -0,0 +1,10 @@
+#include "sampler.hpp"
+
+void Sampler::startPixel(const Vec2d &p) {
+ m_curPixel = p;
+ m_curPixelSampleIndex = 0;
+}
+
+bool Sampler::startNextSample() {
+ return ++m_curPixelSampleIndex < m_sampleCount;
+}
diff --git a/src/sampling/sampler.hpp b/src/sampling/sampler.hpp
new file mode 100644
index 0000000..cd52421
--- /dev/null
+++ b/src/sampling/sampler.hpp
@@ -0,0 +1,52 @@
+#ifndef SAMPLER_H
+#define SAMPLER_H
+
+#include <core/vector.hpp>
+
+#include <memory>
+
+static const double LargestBelowOne = 0x1.fffffffffffffp-1;
+
+class Sampler {
+ public:
+ Sampler(long sampleCount) : m_sampleCount(sampleCount) {}
+
+ /** @brief Start a new pixel sample
+ *
+ * Some samplers might find it usefull to get the position
+ */
+ void startPixel(const Vec2d &p);
+
+ /** @brief Called by renderers when a new sample begins
+ *
+ * @return Whether this is the last sample
+ */
+ bool startNextSample();
+
+ /** @brief Get a single sample */
+ virtual double getSample() = 0;
+
+ /** @brief Get a 2d sample
+ *
+ * Algorithms can optimize for getting 2d samples
+ */
+ virtual Vec2d get2dSample() = 0;
+
+ /** @brief Clones the sampler
+ *
+ * Usefull when multiple threads need a sampler.
+ *
+ * @param seed Seed to set in cloned sampler
+ */
+ virtual std::unique_ptr<Sampler> clone(int seed) = 0;
+
+ const long m_sampleCount;
+
+ protected:
+ Vec2d m_curPixel;
+ long m_curPixelSampleIndex;
+
+};
+
+
+#endif