pure-noise-0.2.0.0: src/Numeric/Noise/SuperSimplex.hs
{-# LANGUAGE Strict #-}
-- |
-- Maintainer: Jeremy Nuttall <jeremy@jeremy-nuttall.com>
-- Stability: experimental
--
-- This module implements a variation of OpenSimplex2 noise derived from FastNoiseLite.
-- See openSimplex2S
module Numeric.Noise.SuperSimplex (
-- * 2D Noise
noise2,
noise2Base,
) where
import Data.Bits
import Numeric.Noise.Internal
import Numeric.Noise.Internal.Math
noise2 :: (RealFrac a) => Noise2 a
noise2 = Noise2 noise2Base
{-# INLINE noise2 #-}
noise2Base :: (RealFrac a) => Seed -> a -> a -> a
noise2Base seed xo yo =
let f2 = 0.5 * (sqrt3 - 1)
to = (xo + yo) * f2
x = xo + to
y = yo + to
fx = floor x
fy = floor y
xi = x - fromIntegral @Hash fx
yi = y - fromIntegral @Hash fy
i = fx * primeX
j = fy * primeY
i1 = i + primeX
j1 = j + primeY
t = (xi + yi) * g2
x0 = xi - t
y0 = yi - t
a0 = (2 / 3) - x0 * x0 - y0 * y0
v0 = (a0 * a0) * (a0 * a0) * gradCoord2 seed i j x0 y0
v1 =
let g2t = 1 - 2 * g2
a1 =
(2 * g2t * (1 / g2 - 2)) * t
+ ((-2 * g2t * g2t) + a0)
x1 = x0 - g2t
y1 = y0 - g2t
in (a1 * a1) * (a1 * a1) * gradCoord2 seed i1 j1 x1 y1
xmyi = xi - yi
~vgx
| xi + xmyi > 1 =
let ~x2 = x0 + (3 * g2 - 2)
~y2 = y0 + (3 * g2 - 1)
~a2 = (2 / 3) - x2 * x2 - y2 * y2
in if a2 > 0
then
(a2 * a2)
* (a2 * a2)
* gradCoord2 seed (i + (primeX `shiftL` 1)) (j + primeY) x2 y2
else 0
| otherwise =
let ~x2 = x0 + g2
~y2 = y0 + (g2 - 1)
~a2 = (2 / 3) - x2 * x2 - y2 * y2
in if a2 > 0
then
(a2 * a2)
* (a2 * a2)
* gradCoord2 seed i (j + primeY) x2 y2
else 0
~vgy
| yi - xmyi > 1 =
let ~x3 = x0 + (3 * g2 - 1)
~y3 = y0 + (3 * g2 - 2)
~a3 = (2 / 3) - x3 * x3 - y3 * y3
in if a3 > 0
then
(a3 * a3)
* (a3 * a3)
* gradCoord2 seed (i + primeX) (j + (primeY `shiftL` 1)) x3 y3
else 0
| otherwise =
let ~x3 = x0 + (g2 - 1)
~y3 = y0 + g2
~a3 = (2 / 3) - x3 * x3 - y3 * y3
in if a3 > 0
then
(a3 * a3)
* (a3 * a3)
* gradCoord2 seed (i + primeX) j x3 y3
else 0
~vlx
| xi + xmyi < 0 =
let ~x2 = x0 + (1 - g2)
~y2 = y0 - g2
~a2 = (2 / 3) - x2 * x2 - y2 * y2
in if a2 > 0
then
(a2 * a2)
* (a2 * a2)
* gradCoord2 seed (i - primeX) j x2 y2
else 0
| otherwise =
let ~x2 = x0 + (g2 - 1)
~y2 = y0 + g2
~a2 = (2 / 3) - x2 * x2 - y2 * y2
in if a2 > 0
then
(a2 * a2)
* (a2 * a2)
* gradCoord2 seed (i + primeX) j x2 y2
else 0
~vly
| yi < xmyi =
let ~x2 = x0 - g2
~y2 = y0 - (g2 - 1)
~a2 = (2 / 3) - x2 * x2 - y2 * y2
in if a2 > 0
then
(a2 * a2)
* (a2 * a2)
* gradCoord2 seed i (j - primeY) x2 y2
else 0
| otherwise =
let ~x2 = x0 + g2
~y2 = y0 + (g2 - 1)
~a2 = (2 / 3) - x2 * x2 - y2 * y2
in if a2 > 0
then
(a2 * a2)
* (a2 * a2)
* gradCoord2 seed i (j + primeY) x2 y2
else 0
v2
| t > g2 = vgx + vgy
| otherwise = vlx + vly
in (v0 + v1 + v2) * 18.24196194486065
{-# INLINE noise2Base #-}