From a338b2771a442663a2fc7d2fd03dee50e1136885 Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Fri, 15 Apr 2011 19:33:22 +0100 Subject: [PATCH] Updated noise implementation --- glm/core/func_noise.inl | 359 +++++++--------------------------------- 1 file changed, 60 insertions(+), 299 deletions(-) diff --git a/glm/core/func_noise.inl b/glm/core/func_noise.inl index a8e700ec..096d0bdd 100644 --- a/glm/core/func_noise.inl +++ b/glm/core/func_noise.inl @@ -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 + template inline vecType permute ( - vecType const & x0, + genType const & x0, detail::tvec3 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 permute - ( - detail::tvec2 const & x0, - detail::tvec3 const & p - ) + template + 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 - inline genType noise1 - ( - genType const & x - ) - { - GLM_STATIC_ASSERT(detail::type::is_float, "'noise1' only accept floating-point values"); + template + T simplexNoise2(detail::tvec2 const & v) + { + static const detail::tvec4 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 const C = detail::tvec2( + 0.211324865405187134, // (3.0-sqrt(3.0))/6.; + 0.366025403784438597); // 0.5*(sqrt(3.0)-1.); + detail::tvec3 const D = detail::tvec3(0., 0.5, 2.0) * T(3.14159265358979312); - template - inline typename detail::tvec2::value_type noise1 - ( - detail::tvec2 const & x - ) - { - T tmp(0); - for(typename detail::tvec2::size_type i = 0; i < detail::tvec2::value_size(); ++i) - tmp += x[i]; - return noise1(tmp); - } + // First corner + detail::tvec2 i = floor(v + dot(v, detail::tvec2(C.y))); + detail::tvec2 x0 = v - i + dot(i, detail::tvec2(C.x)); - template - inline typename detail::tvec3::value_type noise1 - ( - detail::tvec3 const & x - ) - { - T tmp(0); - for(typename detail::tvec3::size_type i = 0; i < detail::tvec3::value_size(); ++i) - tmp += x[i]; - return noise1(tmp); - } + // Other corners + detail::tvec2 i1 = (x0.x > x0.y) ? detail::tvec2(1, 0) : detail::tvec2(0, 1) ; - template - inline typename detail::tvec4::value_type noise1 - ( - detail::tvec4 const & x - ) - { - T tmp(0); - for(typename detail::tvec4::size_type i = 0; i < detail::tvec4::value_size(); ++i) - tmp += x[i]; - return noise1(tmp); - } + // x0 = x0 - 0. + 0. * C + detail::tvec2 x1 = x0 - i1 + T(1) * detail::tvec2(C.x); + detail::tvec2 x2 = x0 - T(1) + T(2) * detail::tvec2(C.x); - // noise2 - template - inline detail::tvec2 noise2 - ( - genType const & x - ) - { - GLM_STATIC_ASSERT(detail::type::is_float, "'noise2' only accept floating-point values"); + // Permutations + i = mod(i, pParam.x); + detail::tvec3 p = permute( + permute(i.y + detail::tvec3(T(0), i1.y, T(1)), detail::tvec3(pParam)) + + i.x + detail::tvec3(T(0), i1.x, T(1)), detail::tvec3(pParam)); - genType f1 = x * genType(1103515245) + genType(12345); - genType f2 = f1 * genType(1103515245) + genType(12345); - return detail::tvec2( - noise1(f1), - noise1(f2)); - } +#ifndef USE_CIRCLE + // ( N points uniformly over a line, mapped onto a diamond.) + detail::tvec3 x = fract(p / pParam.w) ; + detail::tvec3 h = T(0.5) - abs(x) ; - template - inline detail::tvec2 noise2 - ( - detail::tvec2 const & x - ) - { - GLM_STATIC_ASSERT(detail::type::is_float, "'noise2' only accept floating-point values"); + detail::tvec3 sx = detail::tvec3(lessThan(x, detail::tvec3(D.x))) * T(2) - T(1); + detail::tvec3 sh = detail::tvec3(lessThan(h, detail::tvec3(D.x))); - T f0(0); - for(typename detail::tvec2::size_type i = 0; i < detail::tvec2::value_size(); ++i) - f0 += x[i]; - - T f1 = f0 * T(1103515245) + T(12345); - T f2 = f1 * T(1103515245) + T(12345); - return detail::tvec2( - noise1(f1), - noise1(f2)); - } + detail::tvec3 a0 = x + sx * sh; + detail::tvec2 p0(a0.x, h.x); + detail::tvec2 p1(a0.y, h.y); + detail::tvec2 p2(a0.z, h.z); - template - inline detail::tvec2 noise2 - ( - detail::tvec3 const & x - ) - { - GLM_STATIC_ASSERT(detail::type::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::size_type i = 0; i < detail::tvec3::value_size(); ++i) - f0 += x[i]; - - T f1 = f0 * T(1103515245) + T(12345); - T f2 = f1 * T(1103515245) + T(12345); - return detail::tvec2( - noise1(f1), - noise1(f2)); - } - - template - inline detail::tvec2 noise2 - ( - detail::tvec4 const & x - ) - { - GLM_STATIC_ASSERT(detail::type::is_float, "'noise2' only accept floating-point values"); - - T f0(0); - for(typename detail::tvec4::size_type i = 0; i < detail::tvec4::value_size(); ++i) - f0 += x[i]; - - T f1 = f0 * T(1103515245) + T(12345); - T f2 = f1 * T(1103515245) + T(12345); - return detail::tvec2( - noise1(f1), - noise1(f2)); - } - - // noise3 - template - inline detail::tvec3 noise3 - ( - genType const & x - ) - { - GLM_STATIC_ASSERT(detail::type::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( - noise1(f1), - noise1(f2), - noise1(f3)); - } - - template - inline detail::tvec3 noise3 - ( - detail::tvec2 const & x - ) - { - GLM_STATIC_ASSERT(detail::type::is_float, "'noise3' only accept floating-point values"); - - T f0(0); - for(typename detail::tvec2::size_type i = 0; i < detail::tvec2::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( - noise1(f1), - noise1(f2), - noise1(f3)); - } - - template - inline detail::tvec3 noise3 - ( - detail::tvec3 const & x - ) - { - GLM_STATIC_ASSERT(detail::type::is_float, "'noise3' only accept floating-point values"); - - T f0(0); - for(typename detail::tvec3::size_type i = 0; i < detail::tvec3::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( - noise1(f1), - noise1(f2), - noise1(f3)); - } - - template - inline detail::tvec3 noise3 - ( - detail::tvec4 const & x - ) - { - GLM_STATIC_ASSERT(detail::type::is_float, "'noise3' only accept floating-point values"); - - T f0(0); - for(typename detail::tvec4::size_type i = 0; i < detail::tvec4::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( - noise1(f1), - noise1(f2), - noise1(f3)); - } - - // noise4 - template - inline detail::tvec4 noise4 - ( - genType const & x - ) - { - GLM_STATIC_ASSERT(detail::type::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( - noise1(f1), - noise1(f2), - noise1(f3), - noise1(f4)); - } - - template - inline detail::tvec4 noise4 - ( - detail::tvec2 const & x - ) - { - GLM_STATIC_ASSERT(detail::type::is_float, "'noise4' only accept floating-point values"); - - T f0(0); - for(typename detail::tvec2::size_type i = 0; i < detail::tvec2::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( - noise1(f1), - noise1(f2), - noise1(f3), - noise1(f4)); - } - - template - inline detail::tvec4 noise4 - ( - detail::tvec3 const & x - ) - { - GLM_STATIC_ASSERT(detail::type::is_float, "'noise4' only accept floating-point values"); - - T f0(0); - for(typename detail::tvec3::size_type i = 0; i < detail::tvec3::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( - noise1(f1), - noise1(f2), - noise1(f3), - noise1(f4)); - } - - template - inline detail::tvec4 noise4 - ( - detail::tvec4 const & x - ) - { - GLM_STATIC_ASSERT(detail::type::is_float, "'noise4' only accept floating-point values"); - - T f0(0); - for(typename detail::tvec4::size_type i = 0; i < detail::tvec4::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( - noise1(f1), - noise1(f2), - noise1(f3), - noise1(f4)); - } + detail::tvec3 g = T(2) * detail::tvec3(dot(p0, x0), dot(p1, x1), dot(p2, x2)); +#else + // N points around a unit circle. + detail::tvec3 phi = D.z * mod(p, pParam.w) / pParam.w; + detail::tvec4 a0 = sin(phi.xxyy + D.xyxy); + detail::tvec2 a1 = sin(detail::tvec2(phi.z) + D.xy); + detail::tvec3 g = detail::tvec3( + dot(a0.xy, x0), + dot(detail::tvec2(a0.z, a0.w), x1), + dot(detail::tvec2(a1.x, a1.y), x2)); +#endif + // mix + detail::tvec3 m = max(T(0.5) - detail::tvec3(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