Implement fractal perlin noise
This commit is contained in:
parent
aba0afa15e
commit
040497887c
3 changed files with 87 additions and 0 deletions
|
|
@ -4,6 +4,8 @@
|
|||
#include <psemek/geom/vector.hpp>
|
||||
#include <psemek/pcg/seamless.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace psemek::pcg
|
||||
{
|
||||
|
||||
|
|
@ -37,4 +39,24 @@ namespace psemek::pcg
|
|||
gfx::basic_pixmap<geom::vector<float, 2>> grad_map_;
|
||||
};
|
||||
|
||||
struct fractal_perlin
|
||||
{
|
||||
fractal_perlin() = default;
|
||||
fractal_perlin(std::vector<gfx::basic_pixmap<geom::vector<float, 2>>> grad_maps);
|
||||
fractal_perlin(std::vector<gfx::basic_pixmap<geom::vector<float, 2>>> grad_maps, std::vector<float> weights);
|
||||
fractal_perlin(std::vector<gfx::basic_pixmap<geom::vector<float, 2>>> const & grad_maps, seamless_tag);
|
||||
fractal_perlin(std::vector<gfx::basic_pixmap<geom::vector<float, 2>>> const & grad_maps, std::vector<float> weights, seamless_tag);
|
||||
fractal_perlin(fractal_perlin &&) = default;
|
||||
|
||||
fractal_perlin & operator = (fractal_perlin &&) = default;
|
||||
|
||||
// x \in [0.0 .. 1.0]
|
||||
// y \in [0.0 .. 1.0]
|
||||
float operator()(float x, float y) const;
|
||||
|
||||
private:
|
||||
std::vector<perlin> octaves_;
|
||||
std::vector<float> weights_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,4 +64,68 @@ namespace psemek::pcg
|
|||
return 0.5f + v * 0.5f;
|
||||
}
|
||||
|
||||
static std::vector<float> estimate_weights(std::vector<gfx::basic_pixmap<geom::vector<float, 2>>> const & grad_maps)
|
||||
{
|
||||
std::vector<float> weights(grad_maps.size());
|
||||
|
||||
float sum = 0.f;
|
||||
for (std::size_t i = 0; i < grad_maps.size(); ++i)
|
||||
{
|
||||
auto const & m = grad_maps[i];
|
||||
weights[i] = 1.f / std::sqrt(m.width() * m.width() + m.height() * m.height());
|
||||
sum += weights[i];
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < grad_maps.size(); ++i)
|
||||
weights[i] /= sum;
|
||||
|
||||
return weights;
|
||||
}
|
||||
|
||||
fractal_perlin::fractal_perlin(std::vector<gfx::basic_pixmap<geom::vector<float, 2>>> grad_maps)
|
||||
{
|
||||
weights_ = estimate_weights(grad_maps);
|
||||
|
||||
octaves_.resize(grad_maps.size());
|
||||
for (std::size_t i = 0; i < grad_maps.size(); ++i)
|
||||
octaves_[i] = perlin(std::move(grad_maps[i]));
|
||||
}
|
||||
|
||||
fractal_perlin::fractal_perlin(std::vector<gfx::basic_pixmap<geom::vector<float, 2>>> grad_maps, std::vector<float> weights)
|
||||
: weights_{std::move(weights)}
|
||||
{
|
||||
assert(weights_.size() == grad_maps.size());
|
||||
|
||||
octaves_.resize(grad_maps.size());
|
||||
for (std::size_t i = 0; i < grad_maps.size(); ++i)
|
||||
octaves_[i] = perlin(std::move(grad_maps[i]));
|
||||
}
|
||||
|
||||
fractal_perlin::fractal_perlin(std::vector<gfx::basic_pixmap<geom::vector<float, 2>>> const & grad_maps, seamless_tag)
|
||||
{
|
||||
weights_ = estimate_weights(grad_maps);
|
||||
|
||||
octaves_.resize(grad_maps.size());
|
||||
for (std::size_t i = 0; i < grad_maps.size(); ++i)
|
||||
octaves_[i] = perlin(grad_maps[i], seamless);
|
||||
}
|
||||
|
||||
fractal_perlin::fractal_perlin(std::vector<gfx::basic_pixmap<geom::vector<float, 2>>> const & grad_maps, std::vector<float> weights, seamless_tag)
|
||||
: weights_{std::move(weights)}
|
||||
{
|
||||
assert(weights_.size() == grad_maps.size());
|
||||
|
||||
octaves_.resize(grad_maps.size());
|
||||
for (std::size_t i = 0; i < grad_maps.size(); ++i)
|
||||
octaves_[i] = perlin(grad_maps[i], seamless);
|
||||
}
|
||||
|
||||
float fractal_perlin::operator()(float x, float y) const
|
||||
{
|
||||
float v = 0.f;
|
||||
for (std::size_t i = 0; i < octaves_.size(); ++i)
|
||||
v += weights_[i] * octaves_[i](x, y);
|
||||
return v;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
1
todo.md
1
todo.md
|
|
@ -7,3 +7,4 @@
|
|||
* gfx: design & implement simple rendering pipelines
|
||||
* pcg: add clean Generator, Sampler & Pixmap processor concepts, uniformize interfaces, be type & dimension agnostic when possible
|
||||
* pcg: add more vector & point distributions
|
||||
* pcg: make template fractal generator, replace fractal_perlin with it
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue