n/fractal: use hurst parameters consistently
This commit is contained in:
parent
e98709bfc6
commit
bc1c576297
@ -36,13 +36,15 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
struct fbm {
|
struct fbm {
|
||||||
using seed_t = uint64_t;
|
using seed_t = uint64_t;
|
||||||
|
|
||||||
static constexpr unsigned DEFAULT_OCTAVES = 8;
|
static constexpr unsigned DEFAULT_OCTAVES = 8;
|
||||||
static constexpr T DEFAULT_FREQUENCY = T(0.1);
|
static constexpr T DEFAULT_H = 1;
|
||||||
static constexpr T DEFAULT_LACUNARITY = 2;
|
static constexpr T DEFAULT_FREQUENCY = T(0.1);
|
||||||
static constexpr T DEFAULT_AMPLITUDE = 1;
|
static constexpr T DEFAULT_LACUNARITY = 2;
|
||||||
static constexpr T DEFAULT_GAIN = 1 / T(2);
|
static constexpr T DEFAULT_AMPLITUDE = 1;
|
||||||
|
static constexpr T DEFAULT_GAIN = 1 / DEFAULT_LACUNARITY;
|
||||||
|
|
||||||
fbm (unsigned octaves,
|
fbm (unsigned octaves,
|
||||||
|
T H,
|
||||||
T frequency,
|
T frequency,
|
||||||
T lacunarity,
|
T lacunarity,
|
||||||
T amplitude,
|
T amplitude,
|
||||||
@ -52,6 +54,7 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
|
|
||||||
seed_t seed;
|
seed_t seed;
|
||||||
unsigned octaves;
|
unsigned octaves;
|
||||||
|
T H;
|
||||||
|
|
||||||
T frequency;
|
T frequency;
|
||||||
T lacunarity;
|
T lacunarity;
|
||||||
@ -61,6 +64,10 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
|
|
||||||
B basis;
|
B basis;
|
||||||
constexpr T operator() (util::point<2,T>) const;
|
constexpr T operator() (util::point<2,T>) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
T invAH;
|
||||||
|
T invGH;
|
||||||
};
|
};
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
fbm<T,B>::fbm (unsigned _octaves,
|
fbm<T,B>::fbm (unsigned _octaves,
|
||||||
|
T _H,
|
||||||
T _frequency,
|
T _frequency,
|
||||||
T _lacunarity,
|
T _lacunarity,
|
||||||
T _amplitude,
|
T _amplitude,
|
||||||
@ -32,11 +33,14 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
seed_t _seed):
|
seed_t _seed):
|
||||||
seed (_seed),
|
seed (_seed),
|
||||||
octaves (_octaves),
|
octaves (_octaves),
|
||||||
|
H (_H),
|
||||||
frequency (_frequency),
|
frequency (_frequency),
|
||||||
lacunarity (_lacunarity),
|
lacunarity (_lacunarity),
|
||||||
amplitude (_amplitude),
|
amplitude (_amplitude),
|
||||||
gain (_gain),
|
gain (_gain),
|
||||||
basis (_seed)
|
basis (_seed),
|
||||||
|
invAH (std::pow (amplitude, -H)),
|
||||||
|
invGH (std::pow (gain, H))
|
||||||
{
|
{
|
||||||
CHECK_NEQ (octaves, 0);
|
CHECK_NEQ (octaves, 0);
|
||||||
CHECK_NEQ (frequency, 0);
|
CHECK_NEQ (frequency, 0);
|
||||||
@ -48,6 +52,7 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
fbm<T,B>::fbm ():
|
fbm<T,B>::fbm ():
|
||||||
fbm<T,B> (DEFAULT_OCTAVES,
|
fbm<T,B> (DEFAULT_OCTAVES,
|
||||||
|
DEFAULT_H,
|
||||||
DEFAULT_FREQUENCY,
|
DEFAULT_FREQUENCY,
|
||||||
DEFAULT_LACUNARITY,
|
DEFAULT_LACUNARITY,
|
||||||
DEFAULT_AMPLITUDE,
|
DEFAULT_AMPLITUDE,
|
||||||
@ -63,13 +68,13 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
{
|
{
|
||||||
T total = 0;
|
T total = 0;
|
||||||
T f = frequency;
|
T f = frequency;
|
||||||
T a = amplitude;
|
T a = invAH;
|
||||||
|
|
||||||
for (size_t i = 0; i < octaves; ++i) {
|
for (size_t i = 0; i < octaves; ++i) {
|
||||||
total += basis (p * f) * a;
|
total += basis (p * f) * a;
|
||||||
|
|
||||||
f *= lacunarity;
|
f *= lacunarity;
|
||||||
a *= gain;
|
a *= invGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
|
@ -45,6 +45,10 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
B basis;
|
B basis;
|
||||||
|
|
||||||
constexpr T operator() (util::point<2,T>) const;
|
constexpr T operator() (util::point<2,T>) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
T invAH;
|
||||||
|
T invGH;
|
||||||
};
|
};
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
|
@ -29,7 +29,9 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
lacunarity (2),
|
lacunarity (2),
|
||||||
offset (0.7f),
|
offset (0.7f),
|
||||||
amplitude (1),
|
amplitude (1),
|
||||||
gain (1)
|
gain (1/lacunarity),
|
||||||
|
invAH (std::pow (amplitude, -H)),
|
||||||
|
invGH (std::pow (gain, H))
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
@ -38,20 +40,19 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
constexpr T
|
constexpr T
|
||||||
hetero<T,B>::operator() (util::point<2,T> p) const
|
hetero<T,B>::operator() (util::point<2,T> p) const
|
||||||
{
|
{
|
||||||
T exponents[octaves];
|
T scale = invAH;
|
||||||
for (size_t i = 0; i < octaves; ++i)
|
|
||||||
exponents[i] = std::pow (std::pow (lacunarity, float (i)), -H);
|
|
||||||
|
|
||||||
T result = 0;
|
|
||||||
T increment = 0;
|
|
||||||
|
|
||||||
p *= frequency;
|
p *= frequency;
|
||||||
result = basis (p) + offset;
|
T result = (basis (p) + offset) * scale;
|
||||||
p *= lacunarity;
|
p *= lacunarity;
|
||||||
|
|
||||||
for (size_t i = 0; i < octaves; ++i) {
|
T increment = 0;
|
||||||
|
|
||||||
|
for (size_t i = 1; i < octaves; ++i) {
|
||||||
|
scale *= invGH;
|
||||||
|
|
||||||
increment = basis (p) + offset;
|
increment = basis (p) + offset;
|
||||||
increment *= exponents[i];
|
increment *= scale;
|
||||||
increment *= result;
|
increment *= result;
|
||||||
|
|
||||||
result += increment;
|
result += increment;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
namespace util { namespace noise { namespace fractal {
|
namespace util { namespace noise { namespace fractal {
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
/// Musgrave's "Hybrid MultiFractal"
|
||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
struct hmf {
|
struct hmf {
|
||||||
using seed_t = uint64_t;
|
using seed_t = uint64_t;
|
||||||
@ -44,7 +45,11 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
|
|
||||||
B basis;
|
B basis;
|
||||||
|
|
||||||
constexpr T operator() (util::point<2,T>) const;
|
constexpr T operator() (point<2,T>) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
T invAH;
|
||||||
|
T invGH;
|
||||||
};
|
};
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
namespace util { namespace noise { namespace fractal {
|
namespace util { namespace noise { namespace fractal {
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
// H should be fairly low due to the decreasing weight parameter in eval
|
||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
hmf<T,B>::hmf ():
|
hmf<T,B>::hmf ():
|
||||||
H (0.25f),
|
H (0.25f),
|
||||||
@ -30,7 +31,9 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
lacunarity (2),
|
lacunarity (2),
|
||||||
offset (0.7f),
|
offset (0.7f),
|
||||||
amplitude (1),
|
amplitude (1),
|
||||||
gain (1)
|
gain (1 / lacunarity),
|
||||||
|
invAH (std::pow (amplitude, -H)),
|
||||||
|
invGH (std::pow (gain, H))
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
@ -39,9 +42,7 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
constexpr T
|
constexpr T
|
||||||
hmf<T,B>::operator() (util::point<2,T> p) const
|
hmf<T,B>::operator() (util::point<2,T> p) const
|
||||||
{
|
{
|
||||||
T exponents[octaves];
|
T scale = invAH;
|
||||||
for (size_t i = 0; i < octaves; ++i)
|
|
||||||
exponents[i] = std::pow (std::pow (lacunarity, float (i)), -H);
|
|
||||||
|
|
||||||
T result = 0;
|
T result = 0;
|
||||||
T signal = 0;
|
T signal = 0;
|
||||||
@ -50,13 +51,13 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
p *= frequency;
|
p *= frequency;
|
||||||
|
|
||||||
for (size_t i = 0; i < octaves; ++i) {
|
for (size_t i = 0; i < octaves; ++i) {
|
||||||
signal = (basis (p) + offset) * exponents[i];
|
signal = (basis (p) + offset) * scale;
|
||||||
result += weight * signal;
|
result += signal * weight;
|
||||||
|
|
||||||
weight *= gain * signal;
|
weight *= signal;
|
||||||
if (weight > 1)
|
weight = min (weight, T{1});
|
||||||
weight = 1;
|
|
||||||
|
|
||||||
|
scale *= invGH;
|
||||||
p *= lacunarity;
|
p *= lacunarity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,19 +25,27 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
/// Rigid Multifractal summation, based on Musgrave's algorithm
|
/// Rigid Multifractal summation, based on Musgrave's algorithm
|
||||||
///
|
///
|
||||||
/// octaves: count of layers to be summed
|
/// octaves: count of layers to be summed
|
||||||
|
/// H: hurst parameter (~roughness)
|
||||||
|
/// offset: TODO
|
||||||
/// frequency: point scaling factor for the base octave
|
/// frequency: point scaling factor for the base octave
|
||||||
/// lacunarity: per octave frequency scaling factor
|
/// lacunarity: incremental octave frequency scaling factor
|
||||||
|
/// amplitude: value scaling factor for the base octave
|
||||||
|
/// gain: incremental octave value scaling factor
|
||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
struct rmf {
|
struct rmf {
|
||||||
using seed_t = uint64_t;
|
using seed_t = uint64_t;
|
||||||
|
|
||||||
static constexpr unsigned DEFAULT_OCTAVES = 5;
|
static constexpr unsigned DEFAULT_OCTAVES = 5;
|
||||||
static constexpr T DEFAULT_FREQUENCY = T(1);
|
static constexpr T DEFAULT_H = 1;
|
||||||
|
static constexpr T DEFAULT_OFFSET = 1;
|
||||||
|
static constexpr T DEFAULT_FREQUENCY = 1;
|
||||||
static constexpr T DEFAULT_LACUNARITY = 2;
|
static constexpr T DEFAULT_LACUNARITY = 2;
|
||||||
static constexpr T DEFAULT_AMPLITUDE = 1;
|
static constexpr T DEFAULT_AMPLITUDE = 2;
|
||||||
static constexpr T DEFAULT_GAIN = 2;
|
static constexpr T DEFAULT_GAIN = 1 / DEFAULT_LACUNARITY;
|
||||||
|
|
||||||
rmf (unsigned octaves,
|
rmf (unsigned octaves,
|
||||||
|
T H,
|
||||||
|
T offset,
|
||||||
T frequency,
|
T frequency,
|
||||||
T lacunarity,
|
T lacunarity,
|
||||||
T amplitude,
|
T amplitude,
|
||||||
@ -46,7 +54,10 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
rmf ();
|
rmf ();
|
||||||
|
|
||||||
seed_t seed;
|
seed_t seed;
|
||||||
|
|
||||||
unsigned octaves;
|
unsigned octaves;
|
||||||
|
T H;
|
||||||
|
T offset;
|
||||||
|
|
||||||
T frequency;
|
T frequency;
|
||||||
T lacunarity;
|
T lacunarity;
|
||||||
@ -55,7 +66,12 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
T gain;
|
T gain;
|
||||||
|
|
||||||
B basis;
|
B basis;
|
||||||
|
|
||||||
constexpr T operator() (util::point<2,T>) const;
|
constexpr T operator() (util::point<2,T>) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
T invAH;
|
||||||
|
T invGH;
|
||||||
};
|
};
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
|
@ -24,18 +24,24 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
rmf<T,B>::rmf (unsigned _octaves,
|
rmf<T,B>::rmf (unsigned _octaves,
|
||||||
T _frequency,
|
T _H,
|
||||||
T _lacunarity,
|
T _offset,
|
||||||
T _amplitude,
|
T _frequency,
|
||||||
T _gain,
|
T _lacunarity,
|
||||||
seed_t _seed):
|
T _amplitude,
|
||||||
|
T _gain,
|
||||||
|
seed_t _seed):
|
||||||
seed (_seed),
|
seed (_seed),
|
||||||
octaves (_octaves),
|
octaves (_octaves),
|
||||||
|
H (_H),
|
||||||
|
offset (_offset),
|
||||||
frequency (_frequency),
|
frequency (_frequency),
|
||||||
lacunarity (_lacunarity),
|
lacunarity (_lacunarity),
|
||||||
amplitude (_amplitude),
|
amplitude (_amplitude),
|
||||||
gain (_gain),
|
gain (_gain),
|
||||||
basis (_seed)
|
basis (_seed),
|
||||||
|
invAH (std::pow (amplitude, -H)),
|
||||||
|
invGH (std::pow (gain, H))
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
@ -43,6 +49,8 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
rmf<T,B>::rmf ():
|
rmf<T,B>::rmf ():
|
||||||
rmf<T,B> (DEFAULT_OCTAVES,
|
rmf<T,B> (DEFAULT_OCTAVES,
|
||||||
|
DEFAULT_H,
|
||||||
|
DEFAULT_OFFSET,
|
||||||
DEFAULT_FREQUENCY,
|
DEFAULT_FREQUENCY,
|
||||||
DEFAULT_LACUNARITY,
|
DEFAULT_LACUNARITY,
|
||||||
DEFAULT_AMPLITUDE,
|
DEFAULT_AMPLITUDE,
|
||||||
@ -52,16 +60,13 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
// we use the name 'amplitude' instead of musgrave's 'gain'.
|
||||||
|
// assumes basis distribution [-1,1] and offset ~= 1
|
||||||
template <typename T, typename B>
|
template <typename T, typename B>
|
||||||
constexpr T
|
constexpr T
|
||||||
rmf<T,B>::operator() (util::point<2,T> p) const
|
rmf<T,B>::operator() (util::point<2,T> p) const
|
||||||
{
|
{
|
||||||
const T offset = 1;
|
T scale = invAH;
|
||||||
const T H = 1.f;
|
|
||||||
|
|
||||||
T exponents[octaves];
|
|
||||||
for (size_t i = 0; i < octaves; ++i)
|
|
||||||
exponents[i] = std::pow (std::pow (lacunarity, float (i)), -H);
|
|
||||||
|
|
||||||
T signal = 0;
|
T signal = 0;
|
||||||
T result = 0;
|
T result = 0;
|
||||||
@ -82,12 +87,13 @@ namespace util { namespace noise { namespace fractal {
|
|||||||
signal *= weight;
|
signal *= weight;
|
||||||
|
|
||||||
// contribute to the weight
|
// contribute to the weight
|
||||||
weight = signal * gain;
|
weight = signal * amplitude;
|
||||||
weight = limit (weight, 0, 1);
|
weight = limit (weight, 0, 1);
|
||||||
|
|
||||||
// record and continue
|
// record and continue
|
||||||
result += signal * exponents[i];
|
result += signal * scale;
|
||||||
|
|
||||||
|
scale *= invGH;
|
||||||
p *= lacunarity;
|
p *= lacunarity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user