n/fractal: fix musgrave (aka rigid multifractal)
This commit is contained in:
parent
62000f50a2
commit
fedbef630b
@ -19,30 +19,25 @@
|
||||
#include "debug.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
using util::noise::fractal;
|
||||
using util::noise::fbm;
|
||||
using util::noise::musgrave;
|
||||
using util::noise::rmf;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
fractal<T>::fractal (unsigned _octaves,
|
||||
T _frequency,
|
||||
T _lacunarity):
|
||||
octaves (_octaves),
|
||||
frequency (_frequency),
|
||||
lacunarity (_lacunarity)
|
||||
fractal<T>::fractal ():
|
||||
seed (rand ())
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
fractal<T>::fractal ():
|
||||
octaves (1),
|
||||
frequency (T(0.1)),
|
||||
lacunarity (T(0.6))
|
||||
fractal<T>::fractal (seed_t _seed):
|
||||
seed (_seed)
|
||||
{ ; }
|
||||
|
||||
|
||||
@ -73,15 +68,27 @@ template <typename T, typename B>
|
||||
fbm<T,B>::fbm (unsigned _octaves,
|
||||
T _frequency,
|
||||
T _lacunarity,
|
||||
T _amplitude,
|
||||
T _gain,
|
||||
seed_t _seed):
|
||||
fractal<T> (_octaves, _frequency, _lacunarity),
|
||||
fractal<T> (_seed),
|
||||
octaves (_octaves),
|
||||
frequency (_frequency),
|
||||
lacunarity (_lacunarity),
|
||||
amplitude (_amplitude),
|
||||
gain (_gain),
|
||||
basis (_seed)
|
||||
{ ; }
|
||||
{
|
||||
CHECK_NEQ (octaves, 0);
|
||||
CHECK_NEQ (frequency, 0);
|
||||
CHECK_NEQ (amplitude, 0);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T, typename B>
|
||||
fbm<T,B>::fbm ()
|
||||
fbm<T,B>::fbm ():
|
||||
fbm<T,B> (8, T(0.1), 2, 1, 1/T(2), rand ())
|
||||
{ ; }
|
||||
|
||||
|
||||
@ -90,17 +97,14 @@ template <typename T, typename B>
|
||||
T
|
||||
fbm<T,B>::operator() (T x, T y) const {
|
||||
T total = 0;
|
||||
T f = this->frequency;
|
||||
T a = 1;
|
||||
T a_sum = 0;
|
||||
T f = frequency;
|
||||
T a = amplitude;
|
||||
|
||||
for (size_t i = 0; i < this->octaves; ++i) {
|
||||
for (size_t i = 0; i < octaves; ++i) {
|
||||
total += basis (x * f, y * f) * a;
|
||||
|
||||
f *= 2;
|
||||
|
||||
a_sum += a;
|
||||
a *= this->lacunarity;
|
||||
f *= lacunarity;
|
||||
a *= gain;
|
||||
}
|
||||
|
||||
return total;
|
||||
@ -111,84 +115,93 @@ fbm<T,B>::operator() (T x, T y) const {
|
||||
template struct util::noise::fbm<float, util::noise::cellular<float>>;
|
||||
template struct util::noise::fbm<float, util::noise::gradient<float,util::lerp::linear>>;
|
||||
template struct util::noise::fbm<float, util::noise::gradient<float,util::lerp::quintic>>;
|
||||
template struct util::noise::fbm<float, util::noise::value<float,util::lerp::trunc>>;
|
||||
template struct util::noise::fbm<float, util::noise::value<float,util::lerp::linear>>;
|
||||
template struct util::noise::fbm<float, util::noise::value<float,util::lerp::quintic>>;
|
||||
|
||||
template struct util::noise::fbm<double, util::noise::cellular<double>>;
|
||||
template struct util::noise::fbm<double, util::noise::gradient<double,util::lerp::linear>>;
|
||||
template struct util::noise::fbm<double, util::noise::gradient<double,util::lerp::quintic>>;
|
||||
template struct util::noise::fbm<double, util::noise::value<double,util::lerp::trunc>>;
|
||||
template struct util::noise::fbm<double, util::noise::value<double,util::lerp::linear>>;
|
||||
template struct util::noise::fbm<double, util::noise::value<double,util::lerp::quintic>>;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename B>
|
||||
musgrave<T,B>::musgrave (unsigned _octaves,
|
||||
rmf<T,B>::rmf (unsigned _octaves,
|
||||
T _frequency,
|
||||
T _lacunarity,
|
||||
T _amplitude,
|
||||
T _gain,
|
||||
seed_t _seed):
|
||||
fractal<T> (_octaves, _frequency, _lacunarity),
|
||||
fractal<T> (_seed),
|
||||
octaves (_octaves),
|
||||
frequency (_frequency),
|
||||
lacunarity (_lacunarity),
|
||||
amplitude (_amplitude),
|
||||
gain (_gain),
|
||||
basis (_seed)
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T, typename B>
|
||||
musgrave<T,B>::musgrave ()
|
||||
rmf<T,B>::rmf ():
|
||||
rmf<T,B> (6, T(1), 2, 1, T(2), rand ())
|
||||
{ ; }
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T, typename B>
|
||||
T
|
||||
musgrave<T,B>::operator() (T x, T y) const {
|
||||
T total = 0;
|
||||
T f = this->frequency;
|
||||
T a = 1;
|
||||
rmf<T,B>::operator() (T x, T y) const {
|
||||
T H = 1;
|
||||
T exponents[octaves];
|
||||
T offset = 1;
|
||||
|
||||
T weight = 1;
|
||||
T offset = 1;
|
||||
T gain = 2;
|
||||
T f = 1.f;
|
||||
for (size_t i = 0; i < octaves; ++i) {
|
||||
exponents[i] = std::pow (f, -H);
|
||||
f *= lacunarity;
|
||||
}
|
||||
|
||||
T signal;
|
||||
T signal = 0, result = 0, weight = 1;
|
||||
|
||||
signal = basis (x * f, y * f);
|
||||
signal = std::fabs (signal);
|
||||
signal = offset - signal;
|
||||
signal *= signal;
|
||||
total = signal;
|
||||
x *= frequency;
|
||||
y *= frequency;
|
||||
|
||||
for (size_t i = 1; i < this->octaves; ++i) {
|
||||
f *= 2;
|
||||
a *= this->lacunarity;
|
||||
for (size_t i = 0; i < octaves; ++i) {
|
||||
signal = basis (x, y);
|
||||
signal = std::fabs (signal);
|
||||
signal = offset - signal;
|
||||
|
||||
signal *= signal;
|
||||
signal *= weight;
|
||||
|
||||
weight = signal * gain;
|
||||
weight = limit (weight, 0, 1);
|
||||
|
||||
signal = basis (x * f, y * f);
|
||||
signal = std::fabs (signal);
|
||||
signal = offset - signal;
|
||||
signal *= signal;
|
||||
result += signal * exponents[i];
|
||||
|
||||
signal *= weight;
|
||||
total += signal * a;
|
||||
total = limit (total, 0, 1);
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
}
|
||||
|
||||
return total;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template struct util::noise::musgrave<float, util::noise::cellular<float>>;
|
||||
template struct util::noise::musgrave<float, util::noise::gradient<float,util::lerp::linear>>;
|
||||
template struct util::noise::musgrave<float, util::noise::gradient<float,util::lerp::quintic>>;
|
||||
template struct util::noise::musgrave<float, util::noise::value<float,util::lerp::linear>>;
|
||||
template struct util::noise::musgrave<float, util::noise::value<float,util::lerp::quintic>>;
|
||||
template struct util::noise::rmf<float, util::noise::cellular<float>>;
|
||||
template struct util::noise::rmf<float, util::noise::gradient<float,util::lerp::linear>>;
|
||||
template struct util::noise::rmf<float, util::noise::gradient<float,util::lerp::quintic>>;
|
||||
template struct util::noise::rmf<float, util::noise::value<float,util::lerp::linear>>;
|
||||
template struct util::noise::rmf<float, util::noise::value<float,util::lerp::quintic>>;
|
||||
|
||||
template struct util::noise::musgrave<double, util::noise::cellular<double>>;
|
||||
template struct util::noise::musgrave<double, util::noise::gradient<double,util::lerp::linear>>;
|
||||
template struct util::noise::musgrave<double, util::noise::gradient<double,util::lerp::quintic>>;
|
||||
template struct util::noise::musgrave<double, util::noise::value<double,util::lerp::linear>>;
|
||||
template struct util::noise::musgrave<double, util::noise::value<double,util::lerp::quintic>>;
|
||||
template struct util::noise::rmf<double, util::noise::cellular<double>>;
|
||||
template struct util::noise::rmf<double, util::noise::gradient<double,util::lerp::linear>>;
|
||||
template struct util::noise::rmf<double, util::noise::gradient<double,util::lerp::quintic>>;
|
||||
template struct util::noise::rmf<double, util::noise::value<double,util::lerp::linear>>;
|
||||
template struct util::noise::rmf<double, util::noise::value<double,util::lerp::quintic>>;
|
||||
|
||||
|
@ -24,21 +24,28 @@ namespace util {
|
||||
/// Base noise summation
|
||||
template <typename T>
|
||||
struct fractal {
|
||||
fractal (unsigned octaves,
|
||||
T frequency,
|
||||
T lacunarity);
|
||||
using seed_t = uint64_t;
|
||||
|
||||
fractal (seed_t);
|
||||
fractal ();
|
||||
virtual ~fractal ();
|
||||
|
||||
unsigned octaves;
|
||||
T frequency;
|
||||
T lacunarity;
|
||||
|
||||
virtual T operator() (T x, T y) const = 0;
|
||||
|
||||
seed_t seed;
|
||||
};
|
||||
|
||||
|
||||
/// Fractal Brownian Motion summation.
|
||||
///
|
||||
/// Sum progressive layers of a noise basis with scaling frequency
|
||||
/// and amplitude.
|
||||
///
|
||||
/// octaves: count of layers to be summed
|
||||
/// frequency: point scaling factor for the base octave
|
||||
/// lacunarity: per octave frequency scaling factor
|
||||
/// amplitude: maximum absolute value of the noise
|
||||
/// gain: per octave amplitude scaling factor. typically 1/f.
|
||||
template <typename T, typename B>
|
||||
struct fbm : public fractal<T> {
|
||||
using seed_t = typename basis<T>::seed_t;
|
||||
@ -46,24 +53,48 @@ namespace util {
|
||||
fbm (unsigned octaves,
|
||||
T frequency,
|
||||
T lacunarity,
|
||||
T amplitude,
|
||||
T gain,
|
||||
seed_t seed);
|
||||
fbm ();
|
||||
|
||||
unsigned octaves;
|
||||
|
||||
T frequency;
|
||||
T lacunarity;
|
||||
|
||||
T amplitude;
|
||||
T gain;
|
||||
|
||||
B basis;
|
||||
virtual T operator() (T x, T y) const override;
|
||||
};
|
||||
|
||||
|
||||
/// Rigid Multifractal noise summation.
|
||||
/// Rigid Multifractal noise summation, based on Musgrave's algorithm
|
||||
///
|
||||
/// octaves: count of layers to be summed
|
||||
/// frequency: point scaling factor for the base octave
|
||||
/// lacunarity: per octave frequency scaling factor
|
||||
template <typename T, typename B>
|
||||
struct musgrave : public fractal<T> {
|
||||
struct rmf : public fractal<T> {
|
||||
using seed_t = typename basis<T>::seed_t;
|
||||
|
||||
musgrave (unsigned octaves,
|
||||
rmf (unsigned octaves,
|
||||
T frequency,
|
||||
T lacunarity,
|
||||
T amplitude,
|
||||
T gain,
|
||||
seed_t seed);
|
||||
musgrave ();
|
||||
rmf ();
|
||||
|
||||
unsigned octaves;
|
||||
|
||||
T frequency;
|
||||
T lacunarity;
|
||||
|
||||
T amplitude;
|
||||
T gain;
|
||||
|
||||
B basis;
|
||||
virtual T operator() (T x, T y) const override;
|
||||
|
Loading…
Reference in New Issue
Block a user