noise/basis: add exp weighted perlin gradient basis
useful for terrain generation
This commit is contained in:
parent
96713038d5
commit
0f0e3a8c93
@ -150,6 +150,8 @@ UTIL_FILES = \
|
|||||||
noise/basis/constant.cpp \
|
noise/basis/constant.cpp \
|
||||||
noise/basis/constant.hpp \
|
noise/basis/constant.hpp \
|
||||||
noise/basis/constant.ipp \
|
noise/basis/constant.ipp \
|
||||||
|
noise/basis/expdist.hpp \
|
||||||
|
noise/basis/expdist.ipp \
|
||||||
noise/basis/patch.hpp \
|
noise/basis/patch.hpp \
|
||||||
noise/basis/patch.ipp \
|
noise/basis/patch.ipp \
|
||||||
noise/basis/perlin.hpp \
|
noise/basis/perlin.hpp \
|
||||||
|
48
noise/basis/expgrad.hpp
Normal file
48
noise/basis/expgrad.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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 2015 Danny Robson <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __UTIL_NOISE_BASIS_EXPGRAD_HPP
|
||||||
|
#define __UTIL_NOISE_BASIS_EXPGRAD_HPP
|
||||||
|
|
||||||
|
#include "./gradient.hpp"
|
||||||
|
|
||||||
|
#include "../fwd.hpp"
|
||||||
|
#include "../../point.hpp"
|
||||||
|
#include "../../range.hpp"
|
||||||
|
|
||||||
|
namespace util { namespace noise { namespace basis {
|
||||||
|
template <typename T, lerp_t<T> L>
|
||||||
|
struct expgrad : public gradient<T,L> {
|
||||||
|
explicit expgrad <T,L> (seed_t seed, T base = (T)1.02, T exponent = T{256});
|
||||||
|
|
||||||
|
T base (void) const;
|
||||||
|
T base (T);
|
||||||
|
|
||||||
|
T exponent (void) const;
|
||||||
|
T exponent (T);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
vector<2,T> generate (point<2,intmax_t>) const;
|
||||||
|
|
||||||
|
T m_base;
|
||||||
|
T m_exponent;
|
||||||
|
};
|
||||||
|
} } }
|
||||||
|
|
||||||
|
#include "expgrad.ipp"
|
||||||
|
|
||||||
|
#endif
|
44
noise/basis/expgrad.ipp
Normal file
44
noise/basis/expgrad.ipp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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 <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __UTIL_NOISE_BASIS_EXPGRAD_IPP
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
#define __UTIL_NOISE_BASIS_EXPGRAD_IPP
|
||||||
|
|
||||||
|
#include "../rand.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace util { namespace noise { namespace basis {
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
expgrad<T,L>::expgrad (seed_t _seed, T _base, T _exponent):
|
||||||
|
gradient<T,L> (_seed),
|
||||||
|
m_base (_base),
|
||||||
|
m_exponent (_exponent)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
vector<2,T>
|
||||||
|
expgrad<T,L>::generate (point<2,intmax_t> p) const
|
||||||
|
{
|
||||||
|
auto t = (noise::rand<float> (this->seed (), p) + 1) / 2;
|
||||||
|
auto factor = std::pow (m_base, -t * m_exponent);
|
||||||
|
return factor * gradient<T,L>::generate (p);
|
||||||
|
}
|
||||||
|
} } }
|
44
noise/basis/gradient.hpp
Normal file
44
noise/basis/gradient.hpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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 <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __UTIL_NOISE_BASIS_GRADIENT_HPP
|
||||||
|
#define __UTIL_NOISE_BASIS_GRADIENT_HPP
|
||||||
|
|
||||||
|
#include "../fwd.hpp"
|
||||||
|
#include "../../point.hpp"
|
||||||
|
#include "../../range.hpp"
|
||||||
|
|
||||||
|
namespace util { namespace noise { namespace basis {
|
||||||
|
/// Perlin: interpolated value across each grid space
|
||||||
|
template <typename T, lerp_t<T> L>
|
||||||
|
struct gradient {
|
||||||
|
gradient (seed_t);
|
||||||
|
|
||||||
|
seed_t seed (void) const;
|
||||||
|
seed_t seed (seed_t);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
vector<2,T> generate (point<2,intmax_t>) const;
|
||||||
|
|
||||||
|
seed_t m_seed;
|
||||||
|
};
|
||||||
|
} } }
|
||||||
|
|
||||||
|
#include "gradient.ipp"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
58
noise/basis/gradient.ipp
Normal file
58
noise/basis/gradient.ipp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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 <danny@nerdcruft.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __UTIL_NOISE_BASIS_GRADIENT_IPP
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
#define __UTIL_NOISE_BASIS_GRADIENT_IPP
|
||||||
|
|
||||||
|
#include "../rand.hpp"
|
||||||
|
|
||||||
|
namespace util { namespace noise { namespace basis {
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
gradient<T,L>::gradient (seed_t _seed):
|
||||||
|
m_seed (_seed)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
template <typename T, lerp_t<T> L>
|
||||||
|
seed_t
|
||||||
|
gradient<T,L>::seed (void) const
|
||||||
|
{
|
||||||
|
return m_seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
template <typename T, lerp_t<T> L>
|
||||||
|
seed_t
|
||||||
|
gradient<T,L>::seed (seed_t _seed)
|
||||||
|
{
|
||||||
|
return m_seed = _seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
template <typename T, util::noise::lerp_t<T> L>
|
||||||
|
vector<2,T>
|
||||||
|
gradient<T,L>::generate (point<2,intmax_t> p) const
|
||||||
|
{
|
||||||
|
return noise::rand<2,T> (m_seed, p);
|
||||||
|
}
|
||||||
|
} } }
|
||||||
|
|
@ -18,24 +18,27 @@
|
|||||||
#ifndef __UTIL_NOISE_BASIS_PERLIN_HPP
|
#ifndef __UTIL_NOISE_BASIS_PERLIN_HPP
|
||||||
#define __UTIL_NOISE_BASIS_PERLIN_HPP
|
#define __UTIL_NOISE_BASIS_PERLIN_HPP
|
||||||
|
|
||||||
|
#include "./gradient.hpp"
|
||||||
|
|
||||||
#include "../fwd.hpp"
|
#include "../fwd.hpp"
|
||||||
#include "../../point.hpp"
|
#include "../../point.hpp"
|
||||||
#include "../../range.hpp"
|
#include "../../range.hpp"
|
||||||
|
|
||||||
namespace util { namespace noise { namespace basis {
|
namespace util { namespace noise { namespace basis {
|
||||||
/// Perlin: interpolated value across each grid space
|
/// Perlin: interpolated value across each grid space
|
||||||
template <typename T, lerp_t<T> L>
|
template <
|
||||||
struct perlin {
|
typename T, // arithmetic and result value_type, must be floating point
|
||||||
|
lerp_t<T> L, // gradient interpolation function
|
||||||
|
template < // gradient provider class, must provide generate(point_t)
|
||||||
|
typename,
|
||||||
|
lerp_t<T>
|
||||||
|
> class G = gradient
|
||||||
|
>
|
||||||
|
struct perlin : public G<T,L> {
|
||||||
perlin (seed_t);
|
perlin (seed_t);
|
||||||
|
|
||||||
range<T> bounds (void) const;
|
range<T> bounds (void) const;
|
||||||
T operator() (point<2,T>) const;
|
T operator() (point<2,T>) const;
|
||||||
|
|
||||||
seed_t seed (void) const;
|
|
||||||
seed_t seed (seed_t);
|
|
||||||
|
|
||||||
private:
|
|
||||||
seed_t m_seed;
|
|
||||||
};
|
};
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
|
@ -23,16 +23,16 @@
|
|||||||
|
|
||||||
namespace util { namespace noise { namespace basis {
|
namespace util { namespace noise { namespace basis {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T, util::noise::lerp_t<T> L>
|
template <typename T, util::noise::lerp_t<T> L, template <typename,lerp_t<T>> class G>
|
||||||
perlin<T,L>::perlin (seed_t _seed):
|
perlin<T,L,G>::perlin (seed_t _seed):
|
||||||
m_seed (_seed)
|
G<T,L> (_seed)
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
template <typename T, util::noise::lerp_t<T> L>
|
template <typename T, util::noise::lerp_t<T> L, template <typename,lerp_t<T>> class G>
|
||||||
util::range<T>
|
util::range<T>
|
||||||
perlin<T,L>::bounds (void) const
|
perlin<T,L,G>::bounds (void) const
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
-std::sqrt (T{2}) / 2,
|
-std::sqrt (T{2}) / 2,
|
||||||
@ -42,27 +42,9 @@ namespace util { namespace noise { namespace basis {
|
|||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
template <typename T, lerp_t<T> L>
|
template <typename T, util::noise::lerp_t<T> L, template <typename,lerp_t<T>> class G>
|
||||||
seed_t
|
|
||||||
perlin<T,L>::seed (void) const
|
|
||||||
{
|
|
||||||
return m_seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
template <typename T, lerp_t<T> L>
|
|
||||||
seed_t
|
|
||||||
perlin<T,L>::seed (seed_t _seed)
|
|
||||||
{
|
|
||||||
return m_seed = _seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
template <typename T, util::noise::lerp_t<T> L>
|
|
||||||
T
|
T
|
||||||
perlin<T,L>::operator() (util::point<2,T> p) const
|
perlin<T,L,G>::operator() (util::point<2,T> p) const
|
||||||
{
|
{
|
||||||
// extract integer and fractional parts. be careful to always round down
|
// extract integer and fractional parts. be careful to always round down
|
||||||
// (particularly with negatives) and avoid rounding errors.
|
// (particularly with negatives) and avoid rounding errors.
|
||||||
@ -78,10 +60,10 @@ namespace util { namespace noise { namespace basis {
|
|||||||
auto p3 = p_int + util::vector<2,intmax_t> { 1, 1 };
|
auto p3 = p_int + util::vector<2,intmax_t> { 1, 1 };
|
||||||
|
|
||||||
// generate the corner gradients
|
// generate the corner gradients
|
||||||
auto g0 = noise::rand<2,T> (m_seed, p0);
|
auto g0 = G<T,L>::generate (p0);
|
||||||
auto g1 = noise::rand<2,T> (m_seed, p1);
|
auto g1 = G<T,L>::generate (p1);
|
||||||
auto g2 = noise::rand<2,T> (m_seed, p2);
|
auto g2 = G<T,L>::generate (p2);
|
||||||
auto g3 = noise::rand<2,T> (m_seed, p3);
|
auto g3 = G<T,L>::generate (p3);
|
||||||
|
|
||||||
// compute the dot products
|
// compute the dot products
|
||||||
T v0 = dot (g0, p - p0);
|
T v0 = dot (g0, p - p0);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "noise/fractal/runtime.hpp"
|
#include "noise/fractal/runtime.hpp"
|
||||||
#include "noise/lerp.hpp"
|
#include "noise/lerp.hpp"
|
||||||
#include "noise/basis/constant.hpp"
|
#include "noise/basis/constant.hpp"
|
||||||
|
#include "noise/basis/expgrad.hpp"
|
||||||
#include "noise/basis/value.hpp"
|
#include "noise/basis/value.hpp"
|
||||||
#include "noise/basis/patch.hpp"
|
#include "noise/basis/patch.hpp"
|
||||||
#include "noise/basis/perlin.hpp"
|
#include "noise/basis/perlin.hpp"
|
||||||
@ -36,7 +37,8 @@ enum basis_t {
|
|||||||
VALUE,
|
VALUE,
|
||||||
PERLIN,
|
PERLIN,
|
||||||
WORLEY,
|
WORLEY,
|
||||||
PATCH
|
PATCH,
|
||||||
|
EXPDIST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -70,6 +72,7 @@ operator>> (std::istream &is, basis_t &b)
|
|||||||
name == "perlin" ? PERLIN :
|
name == "perlin" ? PERLIN :
|
||||||
name == "worley" ? WORLEY :
|
name == "worley" ? WORLEY :
|
||||||
name == "patch" ? PATCH :
|
name == "patch" ? PATCH :
|
||||||
|
name == "expgrad" ? EXPDIST :
|
||||||
(is.setstate (std::istream::failbit), b);
|
(is.setstate (std::istream::failbit), b);
|
||||||
|
|
||||||
return is;
|
return is;
|
||||||
@ -85,6 +88,7 @@ operator<< (std::ostream &os, basis_t b)
|
|||||||
case PERLIN: os << "perlin"; return os;
|
case PERLIN: os << "perlin"; return os;
|
||||||
case WORLEY: os << "worley"; return os;
|
case WORLEY: os << "worley"; return os;
|
||||||
case PATCH: os << "patch"; return os;
|
case PATCH: os << "patch"; return os;
|
||||||
|
case EXPDIST: os << "expgrad"; return os;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
unreachable ();
|
unreachable ();
|
||||||
@ -268,6 +272,20 @@ main (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EXPDIST: {
|
||||||
|
switch (lerp) {
|
||||||
|
case LINEAR: b.reset<basis::perlin<float,util::lerp::linear,basis::expgrad>> (seed); break;
|
||||||
|
case CUBIC: b.reset<basis::perlin<float,util::lerp::cubic,basis::expgrad>> (seed); break;
|
||||||
|
case QUINTIC: b.reset<basis::perlin<float,util::lerp::quintic,basis::expgrad>> (seed); break;
|
||||||
|
case COSINE: b.reset<basis::perlin<float,util::lerp::cosine,basis::expgrad>> (seed); break;
|
||||||
|
case TRUNC: b.reset<basis::perlin<float,util::lerp::trunc,basis::expgrad>> (seed); break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
unreachable ();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case VALUE: {
|
case VALUE: {
|
||||||
switch (lerp) {
|
switch (lerp) {
|
||||||
case LINEAR: b.reset<basis::value<float,util::lerp::linear>> (seed); break;
|
case LINEAR: b.reset<basis::value<float,util::lerp::linear>> (seed); break;
|
||||||
|
Loading…
Reference in New Issue
Block a user