多重抖动在书上说的是水平和竖直方面随机交换。
类声明:
#pragma once #ifndef __MULTIJITTERED_HEADER__ #define __MULTIJITTERED_HEADER__ #include "sampler.h" class MultiJittered :public Sampler { public: MultiJittered(); ~MultiJittered(); MultiJittered(const integer samps); MultiJittered(const integer samps, const integer sets); MultiJittered(const MultiJittered& mji); MultiJittered& operator=(const MultiJittered& mji); virtual Sampler* clone() const; virtual void generate_samples(); private: void shuffled_x_coordinates(integer n);//水平抖动 void shuffled_y_coordinates(integer n);//竖直抖动 ldouble subcell_width; }; #endif
类实现:
#include "pch.h" #include "multijittered.h" MultiJittered::MultiJittered() :Sampler() { generate_samples(); } MultiJittered::~MultiJittered() {} MultiJittered::MultiJittered(const integer samps) :Sampler(samps) { generate_samples(); } MultiJittered::MultiJittered(const integer samps, const integer sets) : Sampler(samps, sets) { generate_samples(); } MultiJittered::MultiJittered(const MultiJittered& mji):Sampler(mji) { generate_samples(); } MultiJittered& MultiJittered::operator=(const MultiJittered& mji) { if (this == &mji) return *this; Sampler::operator=(mji); return *this; } Sampler* MultiJittered::clone() const { return new MultiJittered(*this); } void MultiJittered::generate_samples() { integer n = (integer)std::sqrt((ldouble)nsamples); subcell_width = 1.0 / nsamples; for (integer i = 0; i < nsamples * nsets; i++) samples.push_back(Point3()); for (integer p = 0; p < nsets; p++) for (integer i = 0; i < n; i++) for (integer j = 0; j < n; j++) { samples[i * n + j + p * nsamples].x = (i * n + j) * subcell_width + random_ldouble(0, subcell_width); samples[i * n + j + p * nsamples].y = (j * n + i) * subcell_width + random_ldouble(0, subcell_width); } shuffled_x_coordinates(n); shuffled_y_coordinates(n); } void MultiJittered::shuffled_x_coordinates(integer n) { for (integer p = 0; p < nsets; p++) { for (integer i = 0; i < n; i++) for (integer j = 0; j < n; j++) { integer k = random_integer(j, n - 1); std::swap(samples[i * n + j + p * nsamples].x, samples[i * n + k + p * nsamples].x); } } } void MultiJittered::shuffled_y_coordinates(integer n) { for (integer p = 0; p < nsets; p++) { for (integer i = 0; i < n; i++) for (integer j = 0; j < n; j++) { integer k = random_integer(j, n - 1); std::swap(samples[j * n + i + p * nsamples].y, samples[k * n + i + p * nsamples].y); } } }
测试结果图: