From 3bf665116d74976313aec905635388e958956e0e Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Thu, 21 Apr 2011 17:20:56 +0100 Subject: [PATCH] Added snoise (2d) implementation draft --- glm/core/func_noise.inl | 81 ----------------------------------------- glm/ext.hpp | 1 - glm/gtx/noise.hpp | 20 +++++----- glm/gtx/noise.inl | 62 ++++++++++++++++++++++++++++++- test/gtx/gtx-noise.cpp | 2 +- 5 files changed, 72 insertions(+), 94 deletions(-) diff --git a/glm/core/func_noise.inl b/glm/core/func_noise.inl index 096d0bdd..7b9f7c1c 100644 --- a/glm/core/func_noise.inl +++ b/glm/core/func_noise.inl @@ -12,88 +12,7 @@ namespace glm namespace core{ namespace function{ namespace noise{ - namespace detail - { - template - inline vecType permute - ( - genType const & x0, - detail::tvec3 const & p - ) - { - genType x1 = mod(x0 * p.y, p.x); - return floor(mod((x1 + p.z) * x0, p.x)); - } - template - inline T taylorInvSqrt(T const & r) - { - return T(0.83666002653408) + T(0.7) * T(0.85373472095314) - T(0.85373472095314) * r); - } - }//namespace detail - - template - T simplexNoise2(detail::tvec2 const & v) - { - static const detail::tvec4 pParam(17. * 17., 34., 1., 7.); - - 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); - - // First corner - detail::tvec2 i = floor(v + dot(v, detail::tvec2(C.y))); - detail::tvec2 x0 = v - i + dot(i, detail::tvec2(C.x)); - - // Other corners - detail::tvec2 i1 = (x0.x > x0.y) ? detail::tvec2(1, 0) : detail::tvec2(0, 1) ; - - // 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); - - // 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)); - -#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) ; - - 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))); - - 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); - -# ifdef NORMALISE_GRADIENTS - p0 *= taylorInvSqrt(dot(p0, p0)); - p1 *= taylorInvSqrt(dot(p1, p1)); - p2 *= taylorInvSqrt(dot(p2, p2)); -# endif - - 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 diff --git a/glm/ext.hpp b/glm/ext.hpp index 5f1d2121..0bb7bc13 100644 --- a/glm/ext.hpp +++ b/glm/ext.hpp @@ -69,7 +69,6 @@ #include "./gtx/raw_data.hpp" #include "./gtx/reciprocal.hpp" #include "./gtx/rotate_vector.hpp" -#include "./gtx/simplex.hpp" #include "./gtx/spline.hpp" #include "./gtx/std_based_type.hpp" #include "./gtx/string_cast.hpp" diff --git a/glm/gtx/noise.hpp b/glm/gtx/noise.hpp index d83dc460..627f1c16 100644 --- a/glm/gtx/noise.hpp +++ b/glm/gtx/noise.hpp @@ -40,22 +40,22 @@ namespace glm //! Classic perlin noise. //! From GLM_GTX_noise extension. - template - typename vecType::value_type cnoise( - vecType const & p); + template class vecType> + typename T cnoise( + vecType const & p); //! Periodic perlin noise. //! From GLM_GTX_noise extension. - template - typename vecType::value_type pnoise( - vecType const & p, - vecType const & rep); + template class vecType> + typename T pnoise( + vecType const & p, + vecType const & rep); //! Simplex noise. //! From GLM_GTX_noise extension. - template - typename vecType::value_type snoise( - vecType const & p); + template class vecType> + typename T snoise( + vecType const & p); ///@} diff --git a/glm/gtx/noise.inl b/glm/gtx/noise.inl index 3a7c074f..7ff9bba8 100644 --- a/glm/gtx/noise.inl +++ b/glm/gtx/noise.inl @@ -15,12 +15,72 @@ // - GLM core /////////////////////////////////////////////////////////////////////////////////////////////////// -namespace glm{ +namespace glm +{ + template + inline detail::tvec3 permute(detail::tvec3 const & x) + { + return mod(((x * T(34)) + T(1)) * x, T(289)); + } + namespace gtx{ namespace noise { + template + inline T snoise(glm::detail::tvec2 const & v) + { + detail::tvec4 const C = detail::tvec4( + T( 0.211324865405187), // (3.0 - sqrt(3.0)) / 6.0 + T( 0.366025403784439), // 0.5 * (sqrt(3.0) - 1.0) + T(-0.577350269189626), // -1.0 + 2.0 * C.x + T( 0.024390243902439)); // 1.0 / 41.0 + // First corner + detail::tvec2 i = floor(v + dot(v, detail::tvec2(C[1]))); + detail::tvec2 x0 = v - i + dot(i, detail::tvec2(C[0])); + // Other corners + //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 + //i1.y = 1.0 - i1.x; + detail::tvec2 i1 = (x0.x > x0.y) ? detail::tvec2(1, 0) : detail::tvec2(0, 1); + // x0 = x0 - 0.0 + 0.0 * C.xx ; + // x1 = x0 - i1 + 1.0 * C.xx ; + // x2 = x0 - 1.0 + 2.0 * C.xx ; + detail::tvec4 x12 = detail::tvec4(x0.x, x0.y, x0.x, x0.y) + detail::tvec4(C.x, C.x, C.z, C.z); + x12 = detail::tvec4(detail::tvec2(x12) - i1, x12.z, x12.w); + + // Permutations + i = mod(i, T(289)); // Avoid truncation effects in permutation + detail::tvec3 p = permute( + permute(i.y + detail::tvec3(T(0), i1.y, T(1))) + + i.x + detail::tvec3(T(0), i1.x, T(1))); +/* + detail::tvec3 m = max(T(0.5) - detail::tvec3( + dot(x0, x0), + dot(detail::tvec2(x12.x, x12.y), detail::tvec2(x12.x, x12.y)), + dot(detail::tvec2(x12.z, x12.w), detail::tvec2(x12.z, x12.w)), T(0.0)); + m = m * m ; + m = m * m ; + + // Gradients: 41 points uniformly over a line, mapped onto a diamond. + // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) + + detail::tvec3 x = 2.0 * fract(p * C.w) - 1.0; + detail::tvec3 h = abs(x) - 0.5; + detail::tvec3 ox = floor(x + 0.5); + detail::tvec3 a0 = x - ox; + + // Normalise gradients implicitly by scaling m + // Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h ); + m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h); + + // Compute final noise value at P + detail::tvec3 g; + g.x = a0.x * x0.x + h.x * x0.y; + g.yz = a0.yz * x12.xz + h.yz * x12.yw; + return 130.0 * dot(m, g); +*/ + } }//namespace noise }//namespace gtx diff --git a/test/gtx/gtx-noise.cpp b/test/gtx/gtx-noise.cpp index 8bcb4c82..5123be08 100644 --- a/test/gtx/gtx-noise.cpp +++ b/test/gtx/gtx-noise.cpp @@ -13,5 +13,5 @@ int main() { - + float ValueSNoise2D = glm::snoise(glm::vec2(0.5f)); }