Tony-LunarG | b0b195d | 2015-05-13 15:01:06 -0600 | [diff] [blame] | 1 | /////////////////////////////////////////////////////////////////////////////////// |
| 2 | /// OpenGL Mathematics (glm.g-truc.net) |
| 3 | /// |
| 4 | /// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) |
| 5 | /// Permission is hereby granted, free of charge, to any person obtaining a copy |
| 6 | /// of this software and associated documentation files (the "Software"), to deal |
| 7 | /// in the Software without restriction, including without limitation the rights |
| 8 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 9 | /// copies of the Software, and to permit persons to whom the Software is |
| 10 | /// furnished to do so, subject to the following conditions: |
| 11 | /// |
| 12 | /// The above copyright notice and this permission notice shall be included in |
| 13 | /// all copies or substantial portions of the Software. |
| 14 | /// |
| 15 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 16 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 17 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 18 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 19 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 20 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 21 | /// THE SOFTWARE. |
| 22 | /// |
| 23 | /// @ref core |
| 24 | /// @file glm/core/func_noise.inl |
| 25 | /// @date 2008-08-01 / 2011-09-27 |
| 26 | /// @author Christophe Riccio |
| 27 | /////////////////////////////////////////////////////////////////////////////////// |
| 28 | |
| 29 | #include "../detail/_noise.hpp" |
| 30 | #include "./func_common.hpp" |
| 31 | |
| 32 | namespace glm{ |
| 33 | namespace detail |
| 34 | { |
| 35 | template <typename T, precision P> |
| 36 | GLM_FUNC_QUALIFIER detail::tvec4<T, P> grad4(T const & j, detail::tvec4<T, P> const & ip) |
| 37 | { |
| 38 | detail::tvec3<T, P> pXYZ = floor(fract(detail::tvec3<T, P>(j) * detail::tvec3<T, P>(ip)) * T(7)) * ip[2] - T(1); |
| 39 | T pW = static_cast<T>(1.5) - dot(abs(pXYZ), detail::tvec3<T, P>(1)); |
| 40 | detail::tvec4<T, P> s = detail::tvec4<T, P>(lessThan(detail::tvec4<T, P>(pXYZ, pW), detail::tvec4<T, P>(0.0))); |
| 41 | pXYZ = pXYZ + (detail::tvec3<T, P>(s) * T(2) - T(1)) * s.w; |
| 42 | return detail::tvec4<T, P>(pXYZ, pW); |
| 43 | } |
| 44 | }//namespace detail |
| 45 | |
| 46 | template <typename T> |
| 47 | GLM_FUNC_QUALIFIER T noise1(T const & x) |
| 48 | { |
| 49 | return noise1(detail::tvec2<T, defaultp>(x, T(0))); |
| 50 | } |
| 51 | |
| 52 | template <typename T> |
| 53 | GLM_FUNC_QUALIFIER detail::tvec2<T, defaultp> noise2(T const & x) |
| 54 | { |
| 55 | return detail::tvec2<T, defaultp>( |
| 56 | noise1(x + T(0.0)), |
| 57 | noise1(x + T(1.0))); |
| 58 | } |
| 59 | |
| 60 | template <typename T> |
| 61 | GLM_FUNC_QUALIFIER detail::tvec3<T, defaultp> noise3(T const & x) |
| 62 | { |
| 63 | return detail::tvec3<T, defaultp>( |
| 64 | noise1(x - T(1.0)), |
| 65 | noise1(x + T(0.0)), |
| 66 | noise1(x + T(1.0))); |
| 67 | } |
| 68 | |
| 69 | template <typename T> |
| 70 | GLM_FUNC_QUALIFIER detail::tvec4<T, defaultp> noise4(T const & x) |
| 71 | { |
| 72 | return detail::tvec4<T, defaultp>( |
| 73 | noise1(x - T(1.0)), |
| 74 | noise1(x + T(0.0)), |
| 75 | noise1(x + T(1.0)), |
| 76 | noise1(x + T(2.0))); |
| 77 | } |
| 78 | |
| 79 | template <typename T, precision P> |
| 80 | GLM_FUNC_QUALIFIER T noise1(detail::tvec2<T, P> const & v) |
| 81 | { |
| 82 | detail::tvec4<T, P> const C = detail::tvec4<T, P>( |
| 83 | T( 0.211324865405187), // (3.0 - sqrt(3.0)) / 6.0 |
| 84 | T( 0.366025403784439), // 0.5 * (sqrt(3.0) - 1.0) |
| 85 | T(-0.577350269189626), // -1.0 + 2.0 * C.x |
| 86 | T( 0.024390243902439)); // 1.0 / 41.0 |
| 87 | |
| 88 | // First corner |
| 89 | detail::tvec2<T, P> i = floor(v + dot(v, detail::tvec2<T, P>(C[1]))); |
| 90 | detail::tvec2<T, P> x0 = v - i + dot(i, detail::tvec2<T, P>(C[0])); |
| 91 | |
| 92 | // Other corners |
| 93 | //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 |
| 94 | //i1.y = 1.0 - i1.x; |
| 95 | detail::tvec2<T, P> i1 = (x0.x > x0.y) ? detail::tvec2<T, P>(1, 0) : detail::tvec2<T, P>(0, 1); |
| 96 | |
| 97 | // x0 = x0 - 0.0 + 0.0 * C.xx ; |
| 98 | // x1 = x0 - i1 + 1.0 * C.xx ; |
| 99 | // x2 = x0 - 1.0 + 2.0 * C.xx ; |
| 100 | detail::tvec4<T, P> x12 = detail::tvec4<T, P>(x0.x, x0.y, x0.x, x0.y) + detail::tvec4<T, P>(C.x, C.x, C.z, C.z); |
| 101 | x12 = detail::tvec4<T, P>(detail::tvec2<T, P>(x12) - i1, x12.z, x12.w); |
| 102 | |
| 103 | // Permutations |
| 104 | i = mod(i, T(289)); // Avoid truncation effects in permutation |
| 105 | detail::tvec3<T, P> p = detail::permute( |
| 106 | detail::permute(i.y + detail::tvec3<T, P>(T(0), i1.y, T(1))) + i.x + detail::tvec3<T, P>(T(0), i1.x, T(1))); |
| 107 | |
| 108 | detail::tvec3<T, P> m = max(T(0.5) - detail::tvec3<T, P>( |
| 109 | dot(x0, x0), |
| 110 | dot(detail::tvec2<T, P>(x12.x, x12.y), detail::tvec2<T, P>(x12.x, x12.y)), |
| 111 | dot(detail::tvec2<T, P>(x12.z, x12.w), detail::tvec2<T, P>(x12.z, x12.w))), T(0)); |
| 112 | |
| 113 | m = m * m; |
| 114 | m = m * m; |
| 115 | |
| 116 | // Gradients: 41 points uniformly over a line, mapped onto a diamond. |
| 117 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) |
| 118 | |
| 119 | detail::tvec3<T, P> x = static_cast<T>(2) * fract(p * C.w) - T(1); |
| 120 | detail::tvec3<T, P> h = abs(x) - T(0.5); |
| 121 | detail::tvec3<T, P> ox = floor(x + T(0.5)); |
| 122 | detail::tvec3<T, P> a0 = x - ox; |
| 123 | |
| 124 | // Normalise gradients implicitly by scaling m |
| 125 | // Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h ); |
| 126 | m *= static_cast<T>(1.79284291400159) - T(0.85373472095314) * (a0 * a0 + h * h); |
| 127 | |
| 128 | // Compute final noise value at P |
| 129 | detail::tvec3<T, P> g; |
| 130 | g.x = a0.x * x0.x + h.x * x0.y; |
| 131 | //g.yz = a0.yz * x12.xz + h.yz * x12.yw; |
| 132 | g.y = a0.y * x12.x + h.y * x12.y; |
| 133 | g.z = a0.z * x12.z + h.z * x12.w; |
| 134 | return T(130) * dot(m, g); |
| 135 | } |
| 136 | |
| 137 | template <typename T, precision P> |
| 138 | GLM_FUNC_QUALIFIER T noise1(detail::tvec3<T, P> const & v) |
| 139 | { |
| 140 | detail::tvec2<T, P> const C(1.0 / 6.0, 1.0 / 3.0); |
| 141 | detail::tvec4<T, P> const D(0.0, 0.5, 1.0, 2.0); |
| 142 | |
| 143 | // First corner |
| 144 | detail::tvec3<T, P> i(floor(v + dot(v, detail::tvec3<T, P>(C.y)))); |
| 145 | detail::tvec3<T, P> x0(v - i + dot(i, detail::tvec3<T, P>(C.x))); |
| 146 | |
| 147 | // Other corners |
| 148 | detail::tvec3<T, P> g(step(detail::tvec3<T, P>(x0.y, x0.z, x0.x), x0)); |
| 149 | detail::tvec3<T, P> l(T(1) - g); |
| 150 | detail::tvec3<T, P> i1(min(g, detail::tvec3<T, P>(l.z, l.x, l.y))); |
| 151 | detail::tvec3<T, P> i2(max(g, detail::tvec3<T, P>(l.z, l.x, l.y))); |
| 152 | |
| 153 | // x0 = x0 - 0.0 + 0.0 * C.xxx; |
| 154 | // x1 = x0 - i1 + 1.0 * C.xxx; |
| 155 | // x2 = x0 - i2 + 2.0 * C.xxx; |
| 156 | // x3 = x0 - 1.0 + 3.0 * C.xxx; |
| 157 | detail::tvec3<T, P> x1(x0 - i1 + C.x); |
| 158 | detail::tvec3<T, P> x2(x0 - i2 + C.y); // 2.0*C.x = 1/3 = C.y |
| 159 | detail::tvec3<T, P> x3(x0 - D.y); // -1.0+3.0*C.x = -0.5 = -D.y |
| 160 | |
| 161 | // Permutations |
| 162 | i = mod289(i); |
| 163 | detail::tvec4<T, P> p(detail::permute(detail::permute(detail::permute( |
| 164 | i.z + detail::tvec4<T, P>(T(0), i1.z, i2.z, T(1))) + |
| 165 | i.y + detail::tvec4<T, P>(T(0), i1.y, i2.y, T(1))) + |
| 166 | i.x + detail::tvec4<T, P>(T(0), i1.x, i2.x, T(1)))); |
| 167 | |
| 168 | // Gradients: 7x7 points over a square, mapped onto an octahedron. |
| 169 | // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) |
| 170 | T n_ = static_cast<T>(0.142857142857); // 1.0/7.0 |
| 171 | detail::tvec3<T, P> ns(n_ * detail::tvec3<T, P>(D.w, D.y, D.z) - detail::tvec3<T, P>(D.x, D.z, D.x)); |
| 172 | |
| 173 | detail::tvec4<T, P> j(p - T(49) * floor(p * ns.z * ns.z)); // mod(p,7*7) |
| 174 | |
| 175 | detail::tvec4<T, P> x_(floor(j * ns.z)); |
| 176 | detail::tvec4<T, P> y_(floor(j - T(7) * x_)); // mod(j,N) |
| 177 | |
| 178 | detail::tvec4<T, P> x(x_ * ns.x + ns.y); |
| 179 | detail::tvec4<T, P> y(y_ * ns.x + ns.y); |
| 180 | detail::tvec4<T, P> h(T(1) - abs(x) - abs(y)); |
| 181 | |
| 182 | detail::tvec4<T, P> b0(x.x, x.y, y.x, y.y); |
| 183 | detail::tvec4<T, P> b1(x.z, x.w, y.z, y.w); |
| 184 | |
| 185 | // vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; |
| 186 | // vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; |
| 187 | detail::tvec4<T, P> s0(floor(b0) * T(2) + T(1)); |
| 188 | detail::tvec4<T, P> s1(floor(b1) * T(2) + T(1)); |
| 189 | detail::tvec4<T, P> sh(-step(h, detail::tvec4<T, P>(0.0))); |
| 190 | |
| 191 | detail::tvec4<T, P> a0 = detail::tvec4<T, P>(b0.x, b0.z, b0.y, b0.w) + detail::tvec4<T, P>(s0.x, s0.z, s0.y, s0.w) * detail::tvec4<T, P>(sh.x, sh.x, sh.y, sh.y); |
| 192 | detail::tvec4<T, P> a1 = detail::tvec4<T, P>(b1.x, b1.z, b1.y, b1.w) + detail::tvec4<T, P>(s1.x, s1.z, s1.y, s1.w) * detail::tvec4<T, P>(sh.z, sh.z, sh.w, sh.w); |
| 193 | |
| 194 | detail::tvec3<T, P> p0(a0.x, a0.y, h.x); |
| 195 | detail::tvec3<T, P> p1(a0.z, a0.w, h.y); |
| 196 | detail::tvec3<T, P> p2(a1.x, a1.y, h.z); |
| 197 | detail::tvec3<T, P> p3(a1.z, a1.w, h.w); |
| 198 | |
| 199 | // Normalise gradients |
| 200 | detail::tvec4<T, P> norm = taylorInvSqrt(detail::tvec4<T, P>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); |
| 201 | p0 *= norm.x; |
| 202 | p1 *= norm.y; |
| 203 | p2 *= norm.z; |
| 204 | p3 *= norm.w; |
| 205 | |
| 206 | // Mix final noise value |
| 207 | detail::tvec4<T, P> m = max(T(0.6) - detail::tvec4<T, P>(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), T(0)); |
| 208 | m = m * m; |
| 209 | return T(42) * dot(m * m, detail::tvec4<T, P>(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3))); |
| 210 | } |
| 211 | |
| 212 | template <typename T, precision P> |
| 213 | GLM_FUNC_QUALIFIER T noise1(detail::tvec4<T, P> const & v) |
| 214 | { |
| 215 | detail::tvec4<T, P> const C( |
| 216 | 0.138196601125011, // (5 - sqrt(5))/20 G4 |
| 217 | 0.276393202250021, // 2 * G4 |
| 218 | 0.414589803375032, // 3 * G4 |
| 219 | -0.447213595499958); // -1 + 4 * G4 |
| 220 | |
| 221 | // (sqrt(5) - 1)/4 = F4, used once below |
| 222 | T const F4 = static_cast<T>(0.309016994374947451); |
| 223 | |
| 224 | // First corner |
| 225 | detail::tvec4<T, P> i = floor(v + dot(v, detail::tvec4<T, P>(F4))); |
| 226 | detail::tvec4<T, P> x0 = v - i + dot(i, detail::tvec4<T, P>(C.x)); |
| 227 | |
| 228 | // Other corners |
| 229 | |
| 230 | // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI) |
| 231 | detail::tvec4<T, P> i0; |
| 232 | detail::tvec3<T, P> isX = step(detail::tvec3<T, P>(x0.y, x0.z, x0.w), detail::tvec3<T, P>(x0.x)); |
| 233 | detail::tvec3<T, P> isYZ = step(detail::tvec3<T, P>(x0.z, x0.w, x0.w), detail::tvec3<T, P>(x0.y, x0.y, x0.z)); |
| 234 | |
| 235 | // i0.x = dot(isX, vec3(1.0)); |
| 236 | //i0.x = isX.x + isX.y + isX.z; |
| 237 | //i0.yzw = static_cast<T>(1) - isX; |
| 238 | i0 = detail::tvec4<T, P>(isX.x + isX.y + isX.z, T(1) - isX); |
| 239 | |
| 240 | // i0.y += dot(isYZ.xy, vec2(1.0)); |
| 241 | i0.y += isYZ.x + isYZ.y; |
| 242 | |
| 243 | //i0.zw += 1.0 - detail::tvec2<T, P>(isYZ.x, isYZ.y); |
| 244 | i0.z += static_cast<T>(1) - isYZ.x; |
| 245 | i0.w += static_cast<T>(1) - isYZ.y; |
| 246 | i0.z += isYZ.z; |
| 247 | i0.w += static_cast<T>(1) - isYZ.z; |
| 248 | |
| 249 | // i0 now contains the unique values 0,1,2,3 in each channel |
| 250 | detail::tvec4<T, P> i3 = clamp(i0, T(0), T(1)); |
| 251 | detail::tvec4<T, P> i2 = clamp(i0 - T(1), T(0), T(1)); |
| 252 | detail::tvec4<T, P> i1 = clamp(i0 - T(2), T(0), T(1)); |
| 253 | |
| 254 | // x0 = x0 - 0.0 + 0.0 * C.xxxx |
| 255 | // x1 = x0 - i1 + 0.0 * C.xxxx |
| 256 | // x2 = x0 - i2 + 0.0 * C.xxxx |
| 257 | // x3 = x0 - i3 + 0.0 * C.xxxx |
| 258 | // x4 = x0 - 1.0 + 4.0 * C.xxxx |
| 259 | detail::tvec4<T, P> x1 = x0 - i1 + C.x; |
| 260 | detail::tvec4<T, P> x2 = x0 - i2 + C.y; |
| 261 | detail::tvec4<T, P> x3 = x0 - i3 + C.z; |
| 262 | detail::tvec4<T, P> x4 = x0 + C.w; |
| 263 | |
| 264 | // Permutations |
| 265 | i = mod(i, T(289)); |
| 266 | T j0 = detail::permute(detail::permute(detail::permute(detail::permute(i.w) + i.z) + i.y) + i.x); |
| 267 | detail::tvec4<T, P> j1 = detail::permute(detail::permute(detail::permute(detail::permute( |
| 268 | i.w + detail::tvec4<T, P>(i1.w, i2.w, i3.w, T(1))) + |
| 269 | i.z + detail::tvec4<T, P>(i1.z, i2.z, i3.z, T(1))) + |
| 270 | i.y + detail::tvec4<T, P>(i1.y, i2.y, i3.y, T(1))) + |
| 271 | i.x + detail::tvec4<T, P>(i1.x, i2.x, i3.x, T(1))); |
| 272 | |
| 273 | // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope |
| 274 | // 7*7*6 = 294, which is close to the ring size 17*17 = 289. |
| 275 | detail::tvec4<T, P> ip = detail::tvec4<T, P>(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0)); |
| 276 | |
| 277 | detail::tvec4<T, P> p0 = detail::grad4(j0, ip); |
| 278 | detail::tvec4<T, P> p1 = detail::grad4(j1.x, ip); |
| 279 | detail::tvec4<T, P> p2 = detail::grad4(j1.y, ip); |
| 280 | detail::tvec4<T, P> p3 = detail::grad4(j1.z, ip); |
| 281 | detail::tvec4<T, P> p4 = detail::grad4(j1.w, ip); |
| 282 | |
| 283 | // Normalise gradients |
| 284 | detail::tvec4<T, P> norm = detail::taylorInvSqrt(detail::tvec4<T, P>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3))); |
| 285 | p0 *= norm.x; |
| 286 | p1 *= norm.y; |
| 287 | p2 *= norm.z; |
| 288 | p3 *= norm.w; |
| 289 | p4 *= taylorInvSqrt(dot(p4, p4)); |
| 290 | |
| 291 | // Mix contributions from the five corners |
| 292 | detail::tvec3<T, P> m0 = max(T(0.6) - detail::tvec3<T, P>(dot(x0, x0), dot(x1, x1), dot(x2, x2)), T(0)); |
| 293 | detail::tvec2<T, P> m1 = max(T(0.6) - detail::tvec2<T, P>(dot(x3, x3), dot(x4, x4) ), T(0)); |
| 294 | m0 = m0 * m0; |
| 295 | m1 = m1 * m1; |
| 296 | |
| 297 | return T(49) * ( |
| 298 | dot(m0 * m0, detail::tvec3<T, P>(dot(p0, x0), dot(p1, x1), dot(p2, x2))) + |
| 299 | dot(m1 * m1, detail::tvec2<T, P>(dot(p3, x3), dot(p4, x4)))); |
| 300 | } |
| 301 | |
| 302 | template <typename T, precision P> |
| 303 | GLM_FUNC_QUALIFIER detail::tvec2<T, P> noise2(detail::tvec2<T, P> const & x) |
| 304 | { |
| 305 | return detail::tvec2<T, P>( |
| 306 | noise1(x + detail::tvec2<T, P>(0.0)), |
| 307 | noise1(detail::tvec2<T, P>(0.0) - x)); |
| 308 | } |
| 309 | |
| 310 | template <typename T, precision P> |
| 311 | GLM_FUNC_QUALIFIER detail::tvec2<T, P> noise2(detail::tvec3<T, P> const & x) |
| 312 | { |
| 313 | return detail::tvec2<T, P>( |
| 314 | noise1(x + detail::tvec3<T, P>(0.0)), |
| 315 | noise1(detail::tvec3<T, P>(0.0) - x)); |
| 316 | } |
| 317 | |
| 318 | template <typename T, precision P> |
| 319 | GLM_FUNC_QUALIFIER detail::tvec2<T, P> noise2(detail::tvec4<T, P> const & x) |
| 320 | { |
| 321 | return detail::tvec2<T, P>( |
| 322 | noise1(x + detail::tvec4<T, P>(0)), |
| 323 | noise1(detail::tvec4<T, P>(0) - x)); |
| 324 | } |
| 325 | |
| 326 | template <typename T, precision P> |
| 327 | GLM_FUNC_QUALIFIER detail::tvec3<T, P> noise3(detail::tvec2<T, P> const & x) |
| 328 | { |
| 329 | return detail::tvec3<T, P>( |
| 330 | noise1(x - detail::tvec2<T, P>(1.0)), |
| 331 | noise1(x + detail::tvec2<T, P>(0.0)), |
| 332 | noise1(x + detail::tvec2<T, P>(1.0))); |
| 333 | } |
| 334 | |
| 335 | template <typename T, precision P> |
| 336 | GLM_FUNC_QUALIFIER detail::tvec3<T, P> noise3(detail::tvec3<T, P> const & x) |
| 337 | { |
| 338 | return detail::tvec3<T, P>( |
| 339 | noise1(x - detail::tvec3<T, P>(1.0)), |
| 340 | noise1(x + detail::tvec3<T, P>(0.0)), |
| 341 | noise1(x + detail::tvec3<T, P>(1.0))); |
| 342 | } |
| 343 | |
| 344 | template <typename T, precision P> |
| 345 | GLM_FUNC_QUALIFIER detail::tvec3<T, P> noise3(detail::tvec4<T, P> const & x) |
| 346 | { |
| 347 | return detail::tvec3<T, P>( |
| 348 | noise1(x - detail::tvec4<T, P>(1)), |
| 349 | noise1(x + detail::tvec4<T, P>(0)), |
| 350 | noise1(x + detail::tvec4<T, P>(1))); |
| 351 | } |
| 352 | |
| 353 | template <typename T, precision P> |
| 354 | GLM_FUNC_QUALIFIER detail::tvec4<T, P> noise4(detail::tvec2<T, P> const & x) |
| 355 | { |
| 356 | return detail::tvec4<T, P>( |
| 357 | noise1(x - detail::tvec2<T, P>(1)), |
| 358 | noise1(x + detail::tvec2<T, P>(0)), |
| 359 | noise1(x + detail::tvec2<T, P>(1)), |
| 360 | noise1(x + detail::tvec2<T, P>(2))); |
| 361 | } |
| 362 | |
| 363 | |
| 364 | template <typename T, precision P> |
| 365 | GLM_FUNC_QUALIFIER detail::tvec4<T, P> noise4(detail::tvec3<T, P> const & x) |
| 366 | { |
| 367 | return detail::tvec4<T, P>( |
| 368 | noise1(x - detail::tvec3<T, P>(1)), |
| 369 | noise1(x + detail::tvec3<T, P>(0)), |
| 370 | noise1(x + detail::tvec3<T, P>(1)), |
| 371 | noise1(x + detail::tvec3<T, P>(2))); |
| 372 | } |
| 373 | |
| 374 | template <typename T, precision P> |
| 375 | GLM_FUNC_QUALIFIER detail::tvec4<T, P> noise4(detail::tvec4<T, P> const & x) |
| 376 | { |
| 377 | return detail::tvec4<T, P>( |
| 378 | noise1(x - detail::tvec4<T, P>(1)), |
| 379 | noise1(x + detail::tvec4<T, P>(0)), |
| 380 | noise1(x + detail::tvec4<T, P>(1)), |
| 381 | noise1(x + detail::tvec4<T, P>(2))); |
| 382 | } |
| 383 | |
| 384 | }//namespace glm |