From 94217187eb2785939458f08d96c7b1b9e55439ab Mon Sep 17 00:00:00 2001 From: Julian T Date: Sun, 17 Jan 2021 00:09:15 +0100 Subject: Minor changed and draft for random sampling --- src/core/common.hpp | 2 +- src/core/random.hpp | 20 +++++++++++++++++++ src/core/spectrum.hpp | 2 +- src/core/vector.cpp | 14 +++++++++++++ src/core/vector.hpp | 17 ++++++++++++++++ src/render.cpp | 4 +--- src/sampling/random.cpp | 13 ++++++++++++ src/sampling/random.hpp | 18 +++++++++++++++++ src/sampling/sampler.cpp | 10 ++++++++++ src/sampling/sampler.hpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 src/core/random.hpp create mode 100644 src/sampling/random.cpp create mode 100644 src/sampling/random.hpp create mode 100644 src/sampling/sampler.cpp create mode 100644 src/sampling/sampler.hpp 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::infinity() +#define INFTY std::numeric_limits::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 + +// 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 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 #include #include +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 +#include + +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 + +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 + +#include + +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 clone(int seed) = 0; + + const long m_sampleCount; + + protected: + Vec2d m_curPixel; + long m_curPixelSampleIndex; + +}; + + +#endif -- cgit v1.2.3