<?phpnamespace Tools\Art;/** Deterministic value noise and a seeded random generator (the art is the same at every build). */final class Noise{ private static int $seed = 12345; public static function seed(int $seed): void { self::$seed = $seed & 0x7fffffff; } /** 0..1 */ public static function rand(): float { self::$seed = (self::$seed * 1103515245 + 12345) & 0x7fffffff; return self::$seed / 0x7fffffff; } public static function hash(int $x, int $y, int $z = 0): float { $h = ($x * 374761393 + $y * 668265263 + $z * 1274126177) & 0xffffffff; $h = (($h ^ ($h >> 13)) * 1274126177) & 0xffffffff; $h ^= $h >> 16; return ($h & 0xffff) / 65535; } private static function smooth(float $t): float { return $t * $t * (3 - 2 * $t); } /** Tileable 2D value noise: $period cells across. */ public static function value2(float $x, float $y, int $period = 0): float { $x0 = (int)floor($x); $y0 = (int)floor($y); $fx = self::smooth($x - $x0); $fy = self::smooth($y - $y0); $w = fn (int $a): int => $period > 0 ? (($a % $period) + $period) % $period : $a; $a = self::hash($w($x0), $w($y0)); $b = self::hash($w($x0 + 1), $w($y0)); $c = self::hash($w($x0), $w($y0 + 1)); $d = self::hash($w($x0 + 1), $w($y0 + 1)); return ($a + ($b - $a) * $fx) + (($c + ($d - $c) * $fx) - ($a + ($b - $a) * $fx)) * $fy; } /** Fractal tileable noise 0..1. */ public static function fbm(float $x, float $y, int $period, int $octaves = 4): float { $sum = 0.0; $amp = 0.5; $norm = 0.0; for ($o = 0; $o < $octaves; $o++) { $sum += self::value2($x, $y, $period) * $amp; $norm += $amp; $x *= 2; $y *= 2; $period *= 2; $amp *= 0.5; } return $sum / $norm; } public static function value3(float $x, float $y, float $z): float { $x0 = (int)floor($x); $y0 = (int)floor($y); $z0 = (int)floor($z); $fx = self::smooth($x - $x0); $fy = self::smooth($y - $y0); $fz = self::smooth($z - $z0); $l = function (int $zz) use ($x0, $y0, $fx, $fy): float { $a = self::hash($x0, $y0, $zz); $b = self::hash($x0 + 1, $y0, $zz); $c = self::hash($x0, $y0 + 1, $zz); $d = self::hash($x0 + 1, $y0 + 1, $zz); $ab = $a + ($b - $a) * $fx; return $ab + ($c + ($d - $c) * $fx - $ab) * $fy; }; $p = $l($z0); return $p + ($l($z0 + 1) - $p) * $fz; }}