From 2d002c9dce7ab4130d09dd7e32025ddd193fac6e Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Mon, 1 Jun 2015 16:20:50 +1000 Subject: [PATCH] n/fractal: extract each type into seperate units --- Makefile.am | 10 +- noise.hpp | 13 +- noise.ipp | 35 +++++ noise/fractal.cpp | 332 --------------------------------------- noise/fractal.hpp | 158 ------------------- noise/fractal/fbm.cpp | 100 ++++++++++++ noise/fractal/fbm.hpp | 67 ++++++++ noise/fractal/hetero.cpp | 76 +++++++++ noise/fractal/hetero.hpp | 53 +++++++ noise/fractal/hmf.cpp | 75 +++++++++ noise/fractal/hmf.hpp | 52 ++++++ noise/fractal/rmf.cpp | 113 +++++++++++++ noise/fractal/rmf.hpp | 62 ++++++++ tools/noise.cpp | 18 ++- 14 files changed, 657 insertions(+), 507 deletions(-) create mode 100644 noise.ipp delete mode 100644 noise/fractal.cpp delete mode 100644 noise/fractal.hpp create mode 100644 noise/fractal/fbm.cpp create mode 100644 noise/fractal/fbm.hpp create mode 100644 noise/fractal/hetero.cpp create mode 100644 noise/fractal/hetero.hpp create mode 100644 noise/fractal/hmf.cpp create mode 100644 noise/fractal/hmf.hpp create mode 100644 noise/fractal/rmf.cpp create mode 100644 noise/fractal/rmf.hpp diff --git a/Makefile.am b/Makefile.am index b53b0671..8799738f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -145,8 +145,14 @@ UTIL_FILES = \ noise/basis/perlin.hpp \ noise/basis/worley.cpp \ noise/basis/worley.hpp \ - noise/fractal.cpp \ - noise/fractal.hpp \ + noise/fractal/fbm.cpp \ + noise/fractal/fbm.hpp \ + noise/fractal/hetero.cpp \ + noise/fractal/hetero.hpp \ + noise/fractal/hmf.cpp \ + noise/fractal/hmf.hpp \ + noise/fractal/rmf.cpp \ + noise/fractal/rmf.hpp \ noise/lerp.cpp \ noise/lerp.hpp \ noise/lut.cpp \ diff --git a/noise.hpp b/noise.hpp index f4ef02a6..00acc245 100644 --- a/noise.hpp +++ b/noise.hpp @@ -14,23 +14,18 @@ * Copyright 2011-2015 Danny Robson */ -#ifndef __UTIL_PERLIN_HPP -#define __UTIL_PERLIN_HPP +#ifndef __UTIL_NOISE_HPP +#define __UTIL_NOISE_HPP #include #include -#include "noise/basis.hpp" -#include "noise/fractal.hpp" - #include "image.hpp" namespace util { namespace noise { - template - void fill (image::buffer&, const util::noise::fractal&); - - void image2d (uint8_t *restrict pixels, size_t width, size_t height, const util::noise::fractal&); + template + void fill (image::buffer&, const G&); } } diff --git a/noise.ipp b/noise.ipp new file mode 100644 index 00000000..3a62bbb8 --- /dev/null +++ b/noise.ipp @@ -0,0 +1,35 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2011-2015 Danny Robson + */ + +#ifdef __UTIL_NOISE_IPP +#error +#endif +#define __UTIL_NOISE_IPP + +namespace util { namespace noise { + //------------------------------------------------------------------------- + template + void + fill (image::buffer &pixels, const G& gen) + { + size_t h = pixels.h, s = pixels.s, w = pixels.w; + T *data = pixels.data (); + + for (size_t y = 0; y < h; ++y) + for (size_t x = 0; x < w; ++x) + data[y * s + x] = gen ({T(x), T(y)}); + } +} } diff --git a/noise/fractal.cpp b/noise/fractal.cpp deleted file mode 100644 index 04dc44a3..00000000 --- a/noise/fractal.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright 2012 Danny Robson - */ - -#include "fractal.hpp" - -#include "basis/constant.hpp" -#include "basis/value.hpp" -#include "basis/perlin.hpp" -#include "basis/worley.hpp" -#include "lerp.hpp" - -#include "../debug.hpp" - -#include -#include - - -using util::noise::fractal; -using util::noise::fbm; -using util::noise::rmf; -using util::noise::hmf; -using util::noise::hetero; - - -/////////////////////////////////////////////////////////////////////////////// -template -fractal::fractal (): - seed (rand ()) -{ ; } - - -//----------------------------------------------------------------------------- -template -fractal::fractal (seed_t _seed): - seed (_seed) -{ ; } - - -//----------------------------------------------------------------------------- -template -fractal::~fractal () -{ ; } - - -//----------------------------------------------------------------------------- -template -T -fractal::operator() (util::point<2,T>) const -{ - unreachable (); -} - - -//----------------------------------------------------------------------------- -namespace util { namespace noise { - template struct fractal; - template struct fractal; -} } - - -/////////////////////////////////////////////////////////////////////////////// -template -fbm::fbm (unsigned _octaves, - T _frequency, - T _lacunarity, - T _amplitude, - T _gain, - seed_t _seed): - fractal (_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 -fbm::fbm (): - fbm (DEFAULT_OCTAVES, - DEFAULT_FREQUENCY, - DEFAULT_LACUNARITY, - DEFAULT_AMPLITUDE, - DEFAULT_GAIN, - rand ()) -{ ; } - - -//----------------------------------------------------------------------------- -template -T -fbm::operator() (util::point<2,T> p) const { - T total = 0; - T f = frequency; - T a = amplitude; - - for (size_t i = 0; i < octaves; ++i) { - total += basis (p * f) * a; - - f *= lacunarity; - a *= gain; - } - - return total; -} - - -//----------------------------------------------------------------------------- -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; - -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; - - -/////////////////////////////////////////////////////////////////////////////// -template -rmf::rmf (unsigned _octaves, - T _frequency, - T _lacunarity, - T _amplitude, - T _gain, - seed_t _seed): - fractal (_seed), - octaves (_octaves), - frequency (_frequency), - lacunarity (_lacunarity), - amplitude (_amplitude), - gain (_gain), - basis (_seed) -{ ; } - - -//----------------------------------------------------------------------------- -template -rmf::rmf (): - rmf (DEFAULT_OCTAVES, - DEFAULT_FREQUENCY, - DEFAULT_LACUNARITY, - DEFAULT_AMPLITUDE, - DEFAULT_GAIN, - rand ()) -{ ; } - - -//----------------------------------------------------------------------------- -template -T -rmf::operator() (util::point<2,T> p) const { - const T offset = 1; - 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 result = 0; - T weight = 1; - - p *= frequency; - - for (size_t i = 0; i < octaves; ++i) { - // generates ridged noise - signal = basis (p); - signal = std::fabs (signal); - signal = offset - signal; - - // sharpens the ridges - signal *= signal; - - // influence by sharpness of previous iteration - signal *= weight; - - // contribute to the weight - weight = signal * gain; - weight = limit (weight, 0, 1); - - // record and continue - result += signal * exponents[i]; - - p *= lacunarity; - } - - return result; -} - - -//----------------------------------------------------------------------------- -template struct util::noise::rmf>; -template struct util::noise::rmf>; -template struct util::noise::rmf>; -template struct util::noise::rmf>; -template struct util::noise::rmf>; - -template struct util::noise::rmf>; -template struct util::noise::rmf>; -template struct util::noise::rmf>; -template struct util::noise::rmf>; -template struct util::noise::rmf>; - - -//----------------------------------------------------------------------------- -template -hmf::hmf (): - H (0.25f), - octaves (6), - frequency (0.1f), - lacunarity (2), - offset (0.7f), - amplitude (1), - gain (1) -{ ; } - - -//----------------------------------------------------------------------------- -template -T -hmf::operator() (util::point<2,T> p) const -{ - T exponents[octaves]; - for (size_t i = 0; i < octaves; ++i) - exponents[i] = std::pow (std::pow (lacunarity, float (i)), -H); - - T result = 0; - T signal = 0; - T weight = 1; - - p *= frequency; - - for (size_t i = 0; i < octaves; ++i) { - signal = (basis (p) + offset) * exponents[i]; - result += weight * signal; - - weight *= gain * signal; - if (weight > 1) - weight = 1; - - p *= lacunarity; - } - - return result; -} - - -template struct util::noise::hmf>; -template struct util::noise::hmf>; -template struct util::noise::hmf>; -template struct util::noise::hmf>; -template struct util::noise::hmf>; - - -//----------------------------------------------------------------------------- -template -hetero::hetero(): - H (0.75f), - octaves (6), - frequency (0.1f), - lacunarity (2), - offset (0.7f), - amplitude (1), - gain (1) -{ ; } - - -//----------------------------------------------------------------------------- -template -T -hetero::operator() (util::point<2,T> p) const -{ - T exponents[octaves]; - 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; - result = basis (p) + offset; - p *= lacunarity; - - for (size_t i = 0; i < octaves; ++i) { - increment = basis (p) + offset; - increment *= exponents[i]; - increment *= result; - - result += increment; - - p *= lacunarity; - } - - return result; -} - - -template struct util::noise::hetero>; -template struct util::noise::hetero>; -template struct util::noise::hetero>; -template struct util::noise::hetero>; -template struct util::noise::hetero>; diff --git a/noise/fractal.hpp b/noise/fractal.hpp deleted file mode 100644 index f63848f8..00000000 --- a/noise/fractal.hpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright 2012 Danny Robson - */ - -#ifndef __UTIL_NOISE_FRACTAL_HPP -#define __UTIL_NOISE_FRACTAL_HPP - -#include "basis.hpp" - -#include "../point.hpp" - -namespace util { - namespace noise { - /// Base noise summation - template - struct fractal { - fractal (seed_t); - fractal (); - virtual ~fractal (); - - virtual T operator() (util::point<2,T>) 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 - struct fbm : public fractal { - static constexpr unsigned DEFAULT_OCTAVES = 8; - static constexpr T DEFAULT_FREQUENCY = T(0.1); - static constexpr T DEFAULT_LACUNARITY = 2; - static constexpr T DEFAULT_AMPLITUDE = 1; - static constexpr T DEFAULT_GAIN = 1 / T(2); - - 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() (util::point<2,T>) const override; - }; - - - /// Rigid Multifractal 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 - struct rmf : public fractal { - static constexpr unsigned DEFAULT_OCTAVES = 5; - static constexpr T DEFAULT_FREQUENCY = T(1); - static constexpr T DEFAULT_LACUNARITY = 2; - static constexpr T DEFAULT_AMPLITUDE = 1; - static constexpr T DEFAULT_GAIN = 2; - - rmf (unsigned octaves, - T frequency, - T lacunarity, - T amplitude, - T gain, - seed_t seed); - rmf (); - - unsigned octaves; - - T frequency; - T lacunarity; - - T amplitude; - T gain; - - B basis; - virtual T operator() (util::point<2,T>) const override; - }; - - - /////////////////////////////////////////////////////////////////////// - template - struct hmf : public fractal { - hmf (); - - T H; - unsigned octaves; - - T frequency; - T lacunarity; - - T offset; - - T amplitude; - T gain; - - B basis; - - virtual T operator() (util::point<2,T>) const override; - }; - - - /////////////////////////////////////////////////////////////////////// - /// Heterogeneous procedural terrain fucntion: stats by altitude method - template - struct hetero : public fractal { - hetero (); - - T H; - unsigned octaves; - - T frequency; - T lacunarity; - - T offset; - - T amplitude; - T gain; - - B basis; - - virtual T operator() (util::point<2,T>) const override; - }; - } -} - -#endif diff --git a/noise/fractal/fbm.cpp b/noise/fractal/fbm.cpp new file mode 100644 index 00000000..606f4e66 --- /dev/null +++ b/noise/fractal/fbm.cpp @@ -0,0 +1,100 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2012-2015 Danny Robson + */ + +#include "fbm.hpp" + +#include "../basis/constant.hpp" +#include "../basis/perlin.hpp" +#include "../basis/value.hpp" +#include "../basis/worley.hpp" +#include "../lerp.hpp" + +using util::noise::fractal::fbm; + + +/////////////////////////////////////////////////////////////////////////////// +template +fbm::fbm (unsigned _octaves, + T _frequency, + T _lacunarity, + T _amplitude, + T _gain, + seed_t _seed): + seed (_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 +fbm::fbm (): + fbm (DEFAULT_OCTAVES, + DEFAULT_FREQUENCY, + DEFAULT_LACUNARITY, + DEFAULT_AMPLITUDE, + DEFAULT_GAIN, + rand ()) +{ ; } + + +//----------------------------------------------------------------------------- +template +T +fbm::operator() (util::point<2,T> p) const { + T total = 0; + T f = frequency; + T a = amplitude; + + for (size_t i = 0; i < octaves; ++i) { + total += basis (p * f) * a; + + f *= lacunarity; + a *= gain; + } + + return total; +} + + +//----------------------------------------------------------------------------- +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; + +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; +template struct util::noise::fractal::fbm>; + diff --git a/noise/fractal/fbm.hpp b/noise/fractal/fbm.hpp new file mode 100644 index 00000000..1ca93dad --- /dev/null +++ b/noise/fractal/fbm.hpp @@ -0,0 +1,67 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2012-2015 Danny Robson + */ + +#ifndef __UTIL_NOISE_FRACTAL_FBM_HPP +#define __UTIL_NOISE_FRACTAL_FBM_HPP + +#include + +#include "../../point.hpp" + +namespace util { namespace noise { namespace fractal { + /// 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 + struct fbm { + using seed_t = uint64_t; + + static constexpr unsigned DEFAULT_OCTAVES = 8; + static constexpr T DEFAULT_FREQUENCY = T(0.1); + static constexpr T DEFAULT_LACUNARITY = 2; + static constexpr T DEFAULT_AMPLITUDE = 1; + static constexpr T DEFAULT_GAIN = 1 / T(2); + + fbm (unsigned octaves, + T frequency, + T lacunarity, + T amplitude, + T gain, + seed_t seed); + fbm (); + + seed_t seed; + unsigned octaves; + + T frequency; + T lacunarity; + + T amplitude; + T gain; + + B basis; + T operator() (util::point<2,T>) const; + }; +} } } + +#endif diff --git a/noise/fractal/hetero.cpp b/noise/fractal/hetero.cpp new file mode 100644 index 00000000..d0260677 --- /dev/null +++ b/noise/fractal/hetero.cpp @@ -0,0 +1,76 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2012-2015 Danny Robson + */ + +#include "hetero.hpp" + +#include "../basis/constant.hpp" +#include "../basis/perlin.hpp" +#include "../basis/value.hpp" +#include "../basis/worley.hpp" +#include "../lerp.hpp" + +using util::noise::fractal::hetero; + + +//----------------------------------------------------------------------------- +template +hetero::hetero(): + H (0.75f), + octaves (6), + frequency (0.1f), + lacunarity (2), + offset (0.7f), + amplitude (1), + gain (1) +{ ; } + + +//----------------------------------------------------------------------------- +template +T +hetero::operator() (util::point<2,T> p) const +{ + T exponents[octaves]; + 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; + result = basis (p) + offset; + p *= lacunarity; + + for (size_t i = 0; i < octaves; ++i) { + increment = basis (p) + offset; + increment *= exponents[i]; + increment *= result; + + result += increment; + + p *= lacunarity; + } + + return result; +} + + +//----------------------------------------------------------------------------- +template struct util::noise::fractal::hetero>; +template struct util::noise::fractal::hetero>; +template struct util::noise::fractal::hetero>; +template struct util::noise::fractal::hetero>; +template struct util::noise::fractal::hetero>; diff --git a/noise/fractal/hetero.hpp b/noise/fractal/hetero.hpp new file mode 100644 index 00000000..01c54d61 --- /dev/null +++ b/noise/fractal/hetero.hpp @@ -0,0 +1,53 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2012-2015 Danny Robson + */ + +#ifndef __UTIL_NOISE_FRACTAL_HETERO_HPP +#define __UTIL_NOISE_FRACTAL_HETERO_HPP + +#include + +#include "../../point.hpp" + +namespace util { namespace noise { namespace fractal { + /////////////////////////////////////////////////////////////////////// + /// Heterogeneous procedural terrain fucntion: stats by altitude method + template + struct hetero { + using seed_t = uint64_t; + + hetero (); + + seed_t seed; + T H; + unsigned octaves; + + T frequency; + T lacunarity; + + T offset; + + T amplitude; + T gain; + + B basis; + + T operator() (util::point<2,T>) const; + }; +} } } + +#endif + + diff --git a/noise/fractal/hmf.cpp b/noise/fractal/hmf.cpp new file mode 100644 index 00000000..222d25cb --- /dev/null +++ b/noise/fractal/hmf.cpp @@ -0,0 +1,75 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2012-2015 Danny Robson + */ + +#include "hmf.hpp" + +#include "../basis/constant.hpp" +#include "../basis/perlin.hpp" +#include "../basis/value.hpp" +#include "../basis/worley.hpp" +#include "../lerp.hpp" + +using util::noise::fractal::hmf; + + +//----------------------------------------------------------------------------- +template +hmf::hmf (): + H (0.25f), + octaves (6), + frequency (0.1f), + lacunarity (2), + offset (0.7f), + amplitude (1), + gain (1) +{ ; } + + +//----------------------------------------------------------------------------- +template +T +hmf::operator() (util::point<2,T> p) const +{ + T exponents[octaves]; + for (size_t i = 0; i < octaves; ++i) + exponents[i] = std::pow (std::pow (lacunarity, float (i)), -H); + + T result = 0; + T signal = 0; + T weight = 1; + + p *= frequency; + + for (size_t i = 0; i < octaves; ++i) { + signal = (basis (p) + offset) * exponents[i]; + result += weight * signal; + + weight *= gain * signal; + if (weight > 1) + weight = 1; + + p *= lacunarity; + } + + return result; +} + + +template struct util::noise::fractal::hmf>; +template struct util::noise::fractal::hmf>; +template struct util::noise::fractal::hmf>; +template struct util::noise::fractal::hmf>; +template struct util::noise::fractal::hmf>; diff --git a/noise/fractal/hmf.hpp b/noise/fractal/hmf.hpp new file mode 100644 index 00000000..6cbdf39e --- /dev/null +++ b/noise/fractal/hmf.hpp @@ -0,0 +1,52 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2012-2015 Danny Robson + */ + +#ifndef __UTIL_NOISE_FRACTAL_HMF_HPP +#define __UTIL_NOISE_FRACTAL_HMF_HPP + +#include + +#include "../../point.hpp" + +namespace util { namespace noise { namespace fractal { + /////////////////////////////////////////////////////////////////////// + template + struct hmf { + using seed_t = uint64_t; + + hmf (); + + seed_t seed; + + T H; + unsigned octaves; + + T frequency; + T lacunarity; + + T offset; + + T amplitude; + T gain; + + B basis; + + T operator() (util::point<2,T>) const; + }; +} } } + +#endif + diff --git a/noise/fractal/rmf.cpp b/noise/fractal/rmf.cpp new file mode 100644 index 00000000..a20c7d1b --- /dev/null +++ b/noise/fractal/rmf.cpp @@ -0,0 +1,113 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2012-2015 Danny Robson + */ + +#include "rmf.hpp" + +#include "../basis/constant.hpp" +#include "../basis/perlin.hpp" +#include "../basis/value.hpp" +#include "../basis/worley.hpp" +#include "../lerp.hpp" + +using util::noise::fractal::rmf; + + +/////////////////////////////////////////////////////////////////////////////// +template +rmf::rmf (unsigned _octaves, + T _frequency, + T _lacunarity, + T _amplitude, + T _gain, + seed_t _seed): + seed (_seed), + octaves (_octaves), + frequency (_frequency), + lacunarity (_lacunarity), + amplitude (_amplitude), + gain (_gain), + basis (_seed) +{ ; } + + +//----------------------------------------------------------------------------- +template +rmf::rmf (): + rmf (DEFAULT_OCTAVES, + DEFAULT_FREQUENCY, + DEFAULT_LACUNARITY, + DEFAULT_AMPLITUDE, + DEFAULT_GAIN, + rand ()) +{ ; } + + +//----------------------------------------------------------------------------- +template +T +rmf::operator() (util::point<2,T> p) const { + const T offset = 1; + 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 result = 0; + T weight = 1; + + p *= frequency; + + for (size_t i = 0; i < octaves; ++i) { + // generates ridged noise + signal = basis (p); + signal = std::fabs (signal); + signal = offset - signal; + + // sharpens the ridges + signal *= signal; + + // influence by sharpness of previous iteration + signal *= weight; + + // contribute to the weight + weight = signal * gain; + weight = limit (weight, 0, 1); + + // record and continue + result += signal * exponents[i]; + + p *= lacunarity; + } + + return result; +} + + +//----------------------------------------------------------------------------- +template struct util::noise::fractal::rmf>; +template struct util::noise::fractal::rmf>; +template struct util::noise::fractal::rmf>; +template struct util::noise::fractal::rmf>; +template struct util::noise::fractal::rmf>; +template struct util::noise::fractal::rmf>; + +template struct util::noise::fractal::rmf>; +template struct util::noise::fractal::rmf>; +template struct util::noise::fractal::rmf>; +template struct util::noise::fractal::rmf>; +template struct util::noise::fractal::rmf>; diff --git a/noise/fractal/rmf.hpp b/noise/fractal/rmf.hpp new file mode 100644 index 00000000..77a1acf8 --- /dev/null +++ b/noise/fractal/rmf.hpp @@ -0,0 +1,62 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2012-2015 Danny Robson + */ + +#ifndef __UTIL_NOISE_FRACTAL_RMF_HPP +#define __UTIL_NOISE_FRACTAL_RMF_HPP + +#include + +#include "../../point.hpp" + +namespace util { namespace noise { namespace fractal { + /// Rigid Multifractal 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 + struct rmf { + using seed_t = uint64_t; + + static constexpr unsigned DEFAULT_OCTAVES = 5; + static constexpr T DEFAULT_FREQUENCY = T(1); + static constexpr T DEFAULT_LACUNARITY = 2; + static constexpr T DEFAULT_AMPLITUDE = 1; + static constexpr T DEFAULT_GAIN = 2; + + rmf (unsigned octaves, + T frequency, + T lacunarity, + T amplitude, + T gain, + seed_t seed); + rmf (); + + seed_t seed; + unsigned octaves; + + T frequency; + T lacunarity; + + T amplitude; + T gain; + + B basis; + T operator() (util::point<2,T>) const; + }; +} } } + +#endif diff --git a/tools/noise.cpp b/tools/noise.cpp index 1db3ad6c..81ce582c 100644 --- a/tools/noise.cpp +++ b/tools/noise.cpp @@ -1,5 +1,10 @@ #include "image.hpp" #include "noise.hpp" + +#include "noise/fractal/fbm.hpp" +#include "noise/fractal/rmf.hpp" +#include "noise/fractal/hmf.hpp" +#include "noise/fractal/hetero.hpp" #include "noise/lerp.hpp" #include "noise/basis/constant.hpp" #include "noise/basis/value.hpp" @@ -15,11 +20,12 @@ main (void) util::image::buffer img (size); // setup the noise generator - //util::noise::fbm> b; - //util::noise::rmf> b; - //util::noise::hmf> b; - util::noise::hetero> b; - //b.octaves = 3; + util::noise::fractal::fbm> b; + //util::noise::fractal::rmf> b; + //util::noise::fractal::fbm> b; + //util::noise::fractal::rmf> b; + //util::noise::fractal::hetero> b; + b.frequency = 10.f / size.w; b.lacunarity = 2; b.basis.seed = time (NULL); @@ -30,7 +36,7 @@ main (void) for (size_t y = 0; y < size.h; ++y) for (size_t x = 0; x < size.w; ++x) { - auto v = b (util::point2f {float (x), float (y)} + offset); //{x + offset, y + offset}); + auto v = b (util::point2f {float (x), float (y)} + offset); img.data ()[y * size.w + x] = v; } }