瀏覽代碼

Updated noise implementation

Christophe Riccio 14 年之前
父節點
當前提交
a338b2771a
共有 1 個文件被更改,包括 70 次插入309 次删除
  1. 70 309
      glm/core/func_noise.inl

+ 70 - 309
glm/core/func_noise.inl

@@ -2,7 +2,7 @@
 // OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
 // OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Created : 2008-08-01
 // Created : 2008-08-01
-// Updated : 2008-09-23
+// Updated : 2011-04-14
 // Licence : This source is under MIT License
 // Licence : This source is under MIT License
 // File    : glm/core/func_noise.inl
 // File    : glm/core/func_noise.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -14,325 +14,86 @@ namespace glm
 	namespace noise{
 	namespace noise{
     namespace detail
     namespace detail
     {
     {
-        template <typenane valType, typenane vecType> 
+        template <typenane valType, typenane genType> 
         inline vecType permute
         inline vecType permute
         (
         (
-            vecType const & x0,
+            genType const & x0,
             detail::tvec3<valType> const & p 
             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
-        )
-        {
-            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)
+        template <typenane T> 
+        inline T taylorInvSqrt(T const & r)
         {
         {
-            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
     }//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");
-
-		int iNbr = int(x + genType(3) / genType(2)) * 1103515245 + 12345;
-		return genType(int(iNbr / genType(65536)) % 32768) / genType(32767);
-	}
-
-	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);
-	}
-
-	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);
-	}
-
-	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);
-	}
-
-	// 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");
-
-		genType f1 = x * genType(1103515245) + genType(12345);
-		genType f2 = f1 * genType(1103515245) + genType(12345);
-		return detail::tvec2<genType>(
-			noise1(f1),
-			noise1(f2));
-	}
-
-	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");
-
-		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));
-	}
-
-	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");
-
-		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));
-	}
+    template <typename T>
+    T simplexNoise2(detail::tvec2<T> const & v)
+    {
+        static const detail::tvec4<T> pParam(17. * 17., 34., 1., 7.);
+
+        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);
+
+        // 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));
+
+        // Other corners
+        detail::tvec2<T> i1  = (x0.x > x0.y) ? detail::tvec2<T>(1, 0) : detail::tvec2<T>(0, 1) ;
+
+        //  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);
+
+        // 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));
+
+#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) ;
+
+        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)));
+
+        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);
+
+#   ifdef NORMALISE_GRADIENTS
+        p0 *= taylorInvSqrt(dot(p0, p0));
+        p1 *= taylorInvSqrt(dot(p1, p1));
+        p2 *= taylorInvSqrt(dot(p2, p2));
+#   endif
+
+        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 noise
 	}//namespace function
 	}//namespace function