Updated noise implementation
This commit is contained in:
parent
b2ae0a3ce9
commit
a338b2771a
@ -2,7 +2,7 @@
|
||||
// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Created : 2008-08-01
|
||||
// Updated : 2008-09-23
|
||||
// Updated : 2011-04-14
|
||||
// Licence : This source is under MIT License
|
||||
// File : glm/core/func_noise.inl
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -14,325 +14,86 @@ namespace glm
|
||||
namespace noise{
|
||||
namespace detail
|
||||
{
|
||||
template <typenane valType, typenane vecType>
|
||||
template <typenane valType, typenane genType>
|
||||
inline vecType permute
|
||||
(
|
||||
vecType const & x0,
|
||||
genType const & x0,
|
||||
detail::tvec3<valType> const & p
|
||||
)
|
||||
{
|
||||
vecType x1 = mod(x0 * p.y, p.x);
|
||||
return floor( mod( (x1 + p.z) *x0, p.x ));
|
||||
genType x1 = mod(x0 * p.y, p.x);
|
||||
return floor(mod((x1 + p.z) * x0, p.x));
|
||||
}
|
||||
|
||||
inline detail::tvec2<T> permute
|
||||
(
|
||||
detail::tvec2<T> const & x0,
|
||||
detail::tvec3<valType> const & p
|
||||
)
|
||||
template <typenane T>
|
||||
inline T taylorInvSqrt(T const & r)
|
||||
{
|
||||
vec2 x1 = mod(x0 * p.y, p.x);
|
||||
return floor( mod( (x1 + p.z) *x0, p.x ));
|
||||
}
|
||||
|
||||
inline vec3 permute(vec3 x0,vec3 p)
|
||||
{
|
||||
vec3 x1 = mod(x0 * p.y, p.x);
|
||||
return floor( mod( (x1 + p.z) *x0, p.x ));
|
||||
}
|
||||
|
||||
inline vec4 permute(vec4 x0,vec3 p)
|
||||
{
|
||||
vec4 x1 = mod(x0 * p.y, p.x);
|
||||
return floor( mod( (x1 + p.z) *x0, p.x ));
|
||||
return T(0.83666002653408) + T(0.7) * T(0.85373472095314) - T(0.85373472095314) * r);
|
||||
}
|
||||
}//namespace detail
|
||||
|
||||
// noise1
|
||||
template <typename genType>
|
||||
inline genType noise1
|
||||
(
|
||||
genType const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'noise1' only accept floating-point values");
|
||||
template <typename T>
|
||||
T simplexNoise2(detail::tvec2<T> const & v)
|
||||
{
|
||||
static const detail::tvec4<T> pParam(17. * 17., 34., 1., 7.);
|
||||
|
||||
int iNbr = int(x + genType(3) / genType(2)) * 1103515245 + 12345;
|
||||
return genType(int(iNbr / genType(65536)) % 32768) / genType(32767);
|
||||
}
|
||||
detail::tvec2<T> const C = detail::tvec2<T>(
|
||||
0.211324865405187134, // (3.0-sqrt(3.0))/6.;
|
||||
0.366025403784438597); // 0.5*(sqrt(3.0)-1.);
|
||||
detail::tvec3<T> const D = detail::tvec3<T>(0., 0.5, 2.0) * T(3.14159265358979312);
|
||||
|
||||
template <typename T>
|
||||
inline typename detail::tvec2<T>::value_type noise1
|
||||
(
|
||||
detail::tvec2<T> const & x
|
||||
)
|
||||
{
|
||||
T tmp(0);
|
||||
for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
|
||||
tmp += x[i];
|
||||
return noise1(tmp);
|
||||
}
|
||||
// First corner
|
||||
detail::tvec2<T> i = floor(v + dot(v, detail::tvec2<T>(C.y)));
|
||||
detail::tvec2<T> x0 = v - i + dot(i, detail::tvec2<T>(C.x));
|
||||
|
||||
template <typename T>
|
||||
inline typename detail::tvec3<T>::value_type noise1
|
||||
(
|
||||
detail::tvec3<T> const & x
|
||||
)
|
||||
{
|
||||
T tmp(0);
|
||||
for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
|
||||
tmp += x[i];
|
||||
return noise1(tmp);
|
||||
}
|
||||
// Other corners
|
||||
detail::tvec2<T> i1 = (x0.x > x0.y) ? detail::tvec2<T>(1, 0) : detail::tvec2<T>(0, 1) ;
|
||||
|
||||
template <typename T>
|
||||
inline typename detail::tvec4<T>::value_type noise1
|
||||
(
|
||||
detail::tvec4<T> const & x
|
||||
)
|
||||
{
|
||||
T tmp(0);
|
||||
for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
|
||||
tmp += x[i];
|
||||
return noise1(tmp);
|
||||
}
|
||||
// x0 = x0 - 0. + 0. * C
|
||||
detail::tvec2<T> x1 = x0 - i1 + T(1) * detail::tvec2<T>(C.x);
|
||||
detail::tvec2<T> x2 = x0 - T(1) + T(2) * detail::tvec2<T>(C.x);
|
||||
|
||||
// noise2
|
||||
template <typename genType>
|
||||
inline detail::tvec2<genType> noise2
|
||||
(
|
||||
genType const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'noise2' only accept floating-point values");
|
||||
// Permutations
|
||||
i = mod(i, pParam.x);
|
||||
detail::tvec3<T> p = permute(
|
||||
permute(i.y + detail::tvec3<T>(T(0), i1.y, T(1)), detail::tvec3<T>(pParam))
|
||||
+ i.x + detail::tvec3<T>(T(0), i1.x, T(1)), detail::tvec3<T>(pParam));
|
||||
|
||||
genType f1 = x * genType(1103515245) + genType(12345);
|
||||
genType f2 = f1 * genType(1103515245) + genType(12345);
|
||||
return detail::tvec2<genType>(
|
||||
noise1(f1),
|
||||
noise1(f2));
|
||||
}
|
||||
#ifndef USE_CIRCLE
|
||||
// ( N points uniformly over a line, mapped onto a diamond.)
|
||||
detail::tvec3<T> x = fract(p / pParam.w) ;
|
||||
detail::tvec3<T> h = T(0.5) - abs(x) ;
|
||||
|
||||
template <typename T>
|
||||
inline detail::tvec2<T> noise2
|
||||
(
|
||||
detail::tvec2<T> const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<T>::is_float, "'noise2' only accept floating-point values");
|
||||
detail::tvec3<T> sx = detail::tvec3<T>(lessThan(x, detail::tvec3<T>(D.x))) * T(2) - T(1);
|
||||
detail::tvec3<T> sh = detail::tvec3<T>(lessThan(h, detail::tvec3<T>(D.x)));
|
||||
|
||||
T f0(0);
|
||||
for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
|
||||
f0 += x[i];
|
||||
|
||||
T f1 = f0 * T(1103515245) + T(12345);
|
||||
T f2 = f1 * T(1103515245) + T(12345);
|
||||
return detail::tvec2<T>(
|
||||
noise1(f1),
|
||||
noise1(f2));
|
||||
}
|
||||
detail::tvec3<T> a0 = x + sx * sh;
|
||||
detail::tvec2<T> p0(a0.x, h.x);
|
||||
detail::tvec2<T> p1(a0.y, h.y);
|
||||
detail::tvec2<T> p2(a0.z, h.z);
|
||||
|
||||
template <typename T>
|
||||
inline detail::tvec2<T> noise2
|
||||
(
|
||||
detail::tvec3<T> const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<T>::is_float, "'noise2' only accept floating-point values");
|
||||
# ifdef NORMALISE_GRADIENTS
|
||||
p0 *= taylorInvSqrt(dot(p0, p0));
|
||||
p1 *= taylorInvSqrt(dot(p1, p1));
|
||||
p2 *= taylorInvSqrt(dot(p2, p2));
|
||||
# endif
|
||||
|
||||
T f0(0);
|
||||
for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
|
||||
f0 += x[i];
|
||||
|
||||
T f1 = f0 * T(1103515245) + T(12345);
|
||||
T f2 = f1 * T(1103515245) + T(12345);
|
||||
return detail::tvec2<T>(
|
||||
noise1(f1),
|
||||
noise1(f2));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline detail::tvec2<T> noise2
|
||||
(
|
||||
detail::tvec4<T> const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<T>::is_float, "'noise2' only accept floating-point values");
|
||||
|
||||
T f0(0);
|
||||
for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
|
||||
f0 += x[i];
|
||||
|
||||
T f1 = f0 * T(1103515245) + T(12345);
|
||||
T f2 = f1 * T(1103515245) + T(12345);
|
||||
return detail::tvec2<T>(
|
||||
noise1(f1),
|
||||
noise1(f2));
|
||||
}
|
||||
|
||||
// noise3
|
||||
template <typename genType>
|
||||
inline detail::tvec3<genType> noise3
|
||||
(
|
||||
genType const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'noise3' only accept floating-point values");
|
||||
|
||||
genType f1 = x * genType(1103515245) + genType(12345);
|
||||
genType f2 = f1 * genType(1103515245) + genType(12345);
|
||||
genType f3 = f2 * genType(1103515245) + genType(12345);
|
||||
return detail::tvec3<genType>(
|
||||
noise1(f1),
|
||||
noise1(f2),
|
||||
noise1(f3));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline detail::tvec3<T> noise3
|
||||
(
|
||||
detail::tvec2<T> const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<T>::is_float, "'noise3' only accept floating-point values");
|
||||
|
||||
T f0(0);
|
||||
for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
|
||||
f0 += x[i];
|
||||
T f1 = f0 * T(1103515245) + T(12345);
|
||||
T f2 = f1 * T(1103515245) + T(12345);
|
||||
T f3 = f2 * T(1103515245) + T(12345);
|
||||
return detail::tvec3<T>(
|
||||
noise1(f1),
|
||||
noise1(f2),
|
||||
noise1(f3));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline detail::tvec3<T> noise3
|
||||
(
|
||||
detail::tvec3<T> const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<T>::is_float, "'noise3' only accept floating-point values");
|
||||
|
||||
T f0(0);
|
||||
for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
|
||||
f0 += x[i];
|
||||
T f1 = f0 * T(1103515245) + T(12345);
|
||||
T f2 = f1 * T(1103515245) + T(12345);
|
||||
T f3 = f2 * T(1103515245) + T(12345);
|
||||
return detail::tvec3<T>(
|
||||
noise1(f1),
|
||||
noise1(f2),
|
||||
noise1(f3));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline detail::tvec3<T> noise3
|
||||
(
|
||||
detail::tvec4<T> const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<T>::is_float, "'noise3' only accept floating-point values");
|
||||
|
||||
T f0(0);
|
||||
for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
|
||||
f0 += x[i];
|
||||
T f1 = f0 * T(1103515245) + T(12345);
|
||||
T f2 = f1 * T(1103515245) + T(12345);
|
||||
T f3 = f2 * T(1103515245) + T(12345);
|
||||
return detail::tvec3<T>(
|
||||
noise1(f1),
|
||||
noise1(f2),
|
||||
noise1(f3));
|
||||
}
|
||||
|
||||
// noise4
|
||||
template <typename genType>
|
||||
inline detail::tvec4<genType> noise4
|
||||
(
|
||||
genType const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'noise4' only accept floating-point values");
|
||||
|
||||
genType f1 = x * genType(1103515245) + genType(12345);
|
||||
genType f2 = f1 * genType(1103515245) + genType(12345);
|
||||
genType f3 = f2 * genType(1103515245) + genType(12345);
|
||||
genType f4 = f3 * genType(1103515245) + genType(12345);
|
||||
return detail::tvec4<genType>(
|
||||
noise1(f1),
|
||||
noise1(f2),
|
||||
noise1(f3),
|
||||
noise1(f4));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline detail::tvec4<T> noise4
|
||||
(
|
||||
detail::tvec2<T> const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<T>::is_float, "'noise4' only accept floating-point values");
|
||||
|
||||
T f0(0);
|
||||
for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
|
||||
f0 += x[i];
|
||||
T f1 = f0 * T(1103515245) + T(12345);
|
||||
T f2 = f1 * T(1103515245) + T(12345);
|
||||
T f3 = f2 * T(1103515245) + T(12345);
|
||||
T f4 = f3 * T(1103515245) + T(12345);
|
||||
return detail::tvec4<T>(
|
||||
noise1(f1),
|
||||
noise1(f2),
|
||||
noise1(f3),
|
||||
noise1(f4));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline detail::tvec4<T> noise4
|
||||
(
|
||||
detail::tvec3<T> const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<T>::is_float, "'noise4' only accept floating-point values");
|
||||
|
||||
T f0(0);
|
||||
for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size()(); ++i)
|
||||
f0 += x[i];
|
||||
T f1 = f0 * T(1103515245) + T(12345);
|
||||
T f2 = f1 * T(1103515245) + T(12345);
|
||||
T f3 = f2 * T(1103515245) + T(12345);
|
||||
T f4 = f3 * T(1103515245) + T(12345);
|
||||
return detail::tvec4<T>(
|
||||
noise1(f1),
|
||||
noise1(f2),
|
||||
noise1(f3),
|
||||
noise1(f4));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline detail::tvec4<T> noise4
|
||||
(
|
||||
detail::tvec4<T> const & x
|
||||
)
|
||||
{
|
||||
GLM_STATIC_ASSERT(detail::type<T>::is_float, "'noise4' only accept floating-point values");
|
||||
|
||||
T f0(0);
|
||||
for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size()(); ++i)
|
||||
f0 += x[i];
|
||||
T f1 = f0 * T(1103515245) + T(12345);
|
||||
T f2 = f1 * T(1103515245) + T(12345);
|
||||
T f3 = f2 * T(1103515245) + T(12345);
|
||||
T f4 = f3 * T(1103515245) + T(12345);
|
||||
return detail::tvec4<T>(
|
||||
noise1(f1),
|
||||
noise1(f2),
|
||||
noise1(f3),
|
||||
noise1(f4));
|
||||
}
|
||||
detail::tvec3<T> g = T(2) * detail::tvec3<T>(dot(p0, x0), dot(p1, x1), dot(p2, x2));
|
||||
#else
|
||||
// N points around a unit circle.
|
||||
detail::tvec3<T> phi = D.z * mod(p, pParam.w) / pParam.w;
|
||||
detail::tvec4<T> a0 = sin(phi.xxyy + D.xyxy);
|
||||
detail::tvec2<T> a1 = sin(detail::tvec2<T>(phi.z) + D.xy);
|
||||
detail::tvec3<T> g = detail::tvec3<T>(
|
||||
dot(a0.xy, x0),
|
||||
dot(detail::tvec2<T>(a0.z, a0.w), x1),
|
||||
dot(detail::tvec2<T>(a1.x, a1.y), x2));
|
||||
#endif
|
||||
// mix
|
||||
detail::tvec3<T> m = max(T(0.5) - detail::tvec3<T>(dot(x0,x0), dot(x1, x1), dot(x2, x2)), T(0));
|
||||
m = m * m ;
|
||||
return T(1.66666) * T(70) * dot(m * m, g);
|
||||
}
|
||||
|
||||
}//namespace noise
|
||||
}//namespace function
|
||||
|
Loading…
Reference in New Issue
Block a user