Skip to content

Commit

Permalink
sobol
Browse files Browse the repository at this point in the history
  • Loading branch information
Shiina Miyuki committed Nov 1, 2020
1 parent 9d95c14 commit 9edec09
Show file tree
Hide file tree
Showing 7 changed files with 21,308 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/akari/render/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ add_subdirectory(integrators)
add_subdirectory(cameras)
add_subdirectory(materials)
add_subdirectory(lights)
add_subdirectory(samplers)
# add_subdirectory(textures)

2 changes: 1 addition & 1 deletion src/akari/render/closure.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ namespace akari::render {
public:
explicit FresnelSpecular(const Spectrum &R, const Spectrum &T, Float etaA, Float etaB)
: R(R), T(T), etaA(etaA), etaB(etaB), fresnel(etaA, etaB) {}
[[nodiscard]] BSDFType type() const { return BSDFType::SpecularTransmission | BSDFType::SpecularReflection; }
[[nodiscard]] BSDFType type() const override{ return BSDFType::SpecularTransmission | BSDFType::SpecularReflection; }
[[nodiscard]] Float evaluate_pdf(const vec3 &wo, const vec3 &wi) const override { return 0; }
[[nodiscard]] Spectrum evaluate(const vec3 &wo, const vec3 &wi) const override { return Spectrum(0); }
[[nodiscard]] std::optional<BSDFSample> sample(const vec2 &u, const Vec3 &wo) const override;
Expand Down
4 changes: 2 additions & 2 deletions src/akari/render/integrators/pt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ namespace akari::render {
pt.min_depth = min_depth;
pt.max_depth = max_depth;
pt.run_megakernel(camera.get(), ivec2(x, y));
tile.add_sample(vec2(x, y), min(clamp_zero(pt.L), Spectrum(10)), 1.0f);
tile.add_sample(vec2(x, y), min(clamp_zero(pt.L), Spectrum(ray_clamp)), 1.0f);
resources[tid]->release();
}
}
Expand All @@ -112,7 +112,7 @@ namespace akari::render {
int min_depth = 3;
Float ray_clamp = 10;
std::shared_ptr<Integrator> create_integrator(Allocator<> allocator) override {
return make_pmr_shared<PathTracerIntegrator>(allocator, spp, min_depth, max_depth,ray_clamp);
return make_pmr_shared<PathTracerIntegrator>(allocator, spp, min_depth, max_depth, ray_clamp);
}
const char *description() override { return "[Path Tracer]"; }
void object_field(sdl::Parser &parser, sdl::ParserContext &ctx, const std::string &field,
Expand Down
42 changes: 25 additions & 17 deletions src/akari/render/sampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,12 @@
#include <optional>

namespace akari::render {
class Sampler {
public:
virtual Float next1d() = 0;
vec2 next2d() { return vec2(next1d(), next1d()); }
virtual void start_next_sample() = 0;
virtual void set_sample_index(uint64_t idx) = 0;
virtual std::shared_ptr<Sampler> clone(Allocator<> allocator) const = 0;
virtual ~Sampler() = default;
};
class SamplerNode : public SceneGraphNode {
public:
virtual std::shared_ptr<Sampler> create_sampler(Allocator<> allocator) = 0;
};
struct Rng {
Rng(uint64_t sequence = 0) { pcg32_init(sequence); }
uint32_t uniform_u32() { return pcg32(); }
double uniform_float() { return pcg32() / double(0xffffffff); }

class PCGSampler : public Sampler {
private:
uint64_t state = 0x4d595df4d0f33173; // Or something seed-dependent
static uint64_t const multiplier = 6364136223846793005u;
static uint64_t const increment = 1442695040888963407u; // Or an arbitrary odd constant
Expand All @@ -61,13 +52,30 @@ namespace akari::render {
state = seed + increment;
(void)pcg32();
}
};
class Sampler {
public:
virtual Float next1d() = 0;
vec2 next2d() { return vec2(next1d(), next1d()); }
virtual void start_next_sample() = 0;
virtual void set_sample_index(uint64_t idx) = 0;
virtual std::shared_ptr<Sampler> clone(Allocator<> allocator) const = 0;
virtual ~Sampler() = default;
};
class SamplerNode : public SceneGraphNode {
public:
virtual std::shared_ptr<Sampler> create_sampler(Allocator<> allocator) = 0;
};

class PCGSampler : public Sampler {
Rng rng;

public:
void set_sample_index(uint64_t idx) override { pcg32_init(idx); }
Float next1d() override { return Float(pcg32()) / (float)0xffffffff; }
void set_sample_index(uint64_t idx) override { rng = Rng(idx); }
Float next1d() override { return rng.uniform_float(); }

void start_next_sample() override {}
PCGSampler(uint64_t seed = 0u) { pcg32_init(seed); }
PCGSampler(uint64_t seed = 0u) : rng(seed) {}
std::shared_ptr<Sampler> clone(Allocator<> allocator) const override {
return make_pmr_shared<PCGSampler>(allocator, *this);
}
Expand Down
1 change: 1 addition & 0 deletions src/akari/render/samplers/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_plugin(SobolSampler sobol.cpp sobolmat.cpp)
73 changes: 73 additions & 0 deletions src/akari/render/samplers/sobol.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

#define SOBOL_MAX_DIMENSION 21201
// MIT License
//
// Copyright (c) 2020 椎名深雪
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include <akari/render/sampler.h>

#define SOBOL_BITS 32
extern const unsigned int SobolMatrix[SOBOL_MAX_DIMENSION][SOBOL_BITS];

static inline uint32_t cmj_hash_simple(uint32_t i, uint32_t p) {
i = (i ^ 61) ^ p;
i += i << 3;
i ^= i >> 4;
i *= 0x27d4eb2d;
return i;
}

#define SOBOL_SKIP 64
// https://wiki.blender.org/wiki/Source/Render/Cycles/Sobol
static inline float sobol(const unsigned int vectors[][32], unsigned int dimension, unsigned int i, unsigned int rng) {
unsigned int result = 0;
i += SOBOL_SKIP;
for (unsigned int j = 0; i; i >>= 1, j++)
if (i & 1)
result ^= vectors[dimension][j];

float r = result * (1.0f / (float)0xFFFFFFFF);
uint32_t tmp_rng = cmj_hash_simple(dimension, rng);
float shift = tmp_rng * (1.0f / (float)0xFFFFFFFF);
return r + shift - floorf(r + shift);
}
namespace akari::render {
class SobolSampler : public Sampler {
int dimension = 0;
int sample = 0;
int rotation;

public:
void set_sample_index(uint64_t idx) override {
Rng rng(idx);
rotation = rng.uniform_u32();
sample = -1;
}
Float next1d() override { return sobol(SobolMatrix, dimension++, sample, rotation); }
void start_next_sample() override {
dimension = 0;
sample++;
}
SobolSampler() { rotation = 0; }
std::shared_ptr<Sampler> clone(Allocator<> allocator) const override {
return make_pmr_shared<SobolSampler>(allocator, *this);
}
};
} // namespace akari::render
Loading

0 comments on commit 9edec09

Please sign in to comment.