From 2541a6d96ca0393311eb0797a0de954f376824aa Mon Sep 17 00:00:00 2001 From: spatialfree Date: Thu, 19 Dec 2024 04:08:11 -0500 Subject: [PATCH] noise rng maths --- src/Maths.cs | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/VFX.cs | 4 +- 2 files changed, 122 insertions(+), 3 deletions(-) diff --git a/src/Maths.cs b/src/Maths.cs index ef31c57..0d54b69 100644 --- a/src/Maths.cs +++ b/src/Maths.cs @@ -35,7 +35,10 @@ public static class Maths // public static int roundi(float value) => MathF.Round(value) public static float precision(float x, float p) - => round(x * p) / p; + { + float ps = p < 1.0f ? 1 / p : p; + return round(x * ps) / ps; + } public static float smooth_start(float t) => (t * t * t); public static float smooth_stop(float t) @@ -94,6 +97,122 @@ public static class Maths } } +/// +/// SquirrelNoise5 - Squirrel's Raw Noise utilities (version 5) +/// Converted to C# from original C++ implementation by Squirrel Eiserloh +/// +public static class Noise +{ + // Bit noise constants + private const uint SQ5_BIT_NOISE1 = 0xd2a80a3f; + private const uint SQ5_BIT_NOISE2 = 0xa884f197; + private const uint SQ5_BIT_NOISE3 = 0x6C736F4B; + private const uint SQ5_BIT_NOISE4 = 0xB79F3ABB; + private const uint SQ5_BIT_NOISE5 = 0x1b56c4f5; + + // Constants for higher dimensional noise + private const int PRIME1 = 198491317; + private const int PRIME2 = 6542989; + private const int PRIME3 = 357239; + + /// + /// Fast hash of an int32 into a different (unrecognizable) uint32 + /// + private static uint GetNoise(int positionX, uint seed) + { + uint mangledBits = (uint)positionX; + mangledBits *= SQ5_BIT_NOISE1; + mangledBits += seed; + mangledBits ^= (mangledBits >> 9); + mangledBits += SQ5_BIT_NOISE2; + mangledBits ^= (mangledBits >> 11); + mangledBits *= SQ5_BIT_NOISE3; + mangledBits ^= (mangledBits >> 13); + mangledBits += SQ5_BIT_NOISE4; + mangledBits ^= (mangledBits >> 15); + mangledBits *= SQ5_BIT_NOISE5; + mangledBits ^= (mangledBits >> 17); + return mangledBits; + } + + // 1D Noise Functions + public static uint u_int_x(int x, uint seed = 0) + { + return GetNoise(x, seed); + } + + public static float u_scalar_x(int x, uint seed = 0) + { + return (float)(GetNoise(x, seed) / (double)uint.MaxValue); + } + + public static float s_scalar_x(int x, uint seed = 0) + { + return (float)((int)GetNoise(x, seed) / (double)int.MaxValue); + } + + private static int step; + static int stepper + { + get + { + step = (step + 1) % 100_000; // [!] magic number + return step; + } + } + public static uint u_int => u_int_x(stepper); + public static float u_scalar => u_scalar_x(stepper); + public static float s_scalar => s_scalar_x(stepper); + + // // 2D Noise Functions + // public static uint Get2dNoiseUint(int indexX, int indexY, uint seed = 0) + // { + // return GetNoise(indexX + (PRIME1 * indexY), seed); + // } + + // public static float Get2dNoiseZeroToOne(int indexX, int indexY, uint seed = 0) + // { + // return (float)(Get2dNoiseUint(indexX, indexY, seed) / (double)uint.MaxValue); + // } + + // public static float Get2dNoiseNegOneToOne(int indexX, int indexY, uint seed = 0) + // { + // return (float)((int)Get2dNoiseUint(indexX, indexY, seed) / (double)int.MaxValue); + // } + + // 3D Noise Functions + public static uint u_int_xyz(int x, int y, int z, uint seed = 0) + { + return GetNoise(x + (PRIME1 * y) + (PRIME2 * z), seed); + } + + public static float u_scalar_xyz(int x, int y, int z, uint seed = 0) + { + return (float)(u_int_xyz(x, y, z, seed) / (double)uint.MaxValue); + } + + public static float s_scalar_xyz(int x, int y, int z, uint seed = 0) + { + return (float)((int)u_int_xyz(x, y, z, seed) / (double)int.MaxValue); + } + + // // 4D Noise Functions + // public static uint Get4dNoiseUint(int indexX, int indexY, int indexZ, int indexT, uint seed = 0) + // { + // return GetNoise(indexX + (PRIME1 * indexY) + (PRIME2 * indexZ) + (PRIME3 * indexT), seed); + // } + + // public static float Get4dNoiseZeroToOne(int indexX, int indexY, int indexZ, int indexT, uint seed = 0) + // { + // return (float)(Get4dNoiseUint(indexX, indexY, indexZ, indexT, seed) / (double)uint.MaxValue); + // } + + // public static float Get4dNoiseNegOneToOne(int indexX, int indexY, int indexZ, int indexT, uint seed = 0) + // { + // return (float)((int)Get4dNoiseUint(indexX, indexY, indexZ, indexT, seed) / (double)int.MaxValue); + // } +} + public class DeltaBool { public int delta = 0; diff --git a/src/VFX.cs b/src/VFX.cs index adcb901..a57f225 100644 --- a/src/VFX.cs +++ b/src/VFX.cs @@ -23,9 +23,9 @@ static class VFX index = (index + 1) % particles.Length; Particle particle = particles[index]; particle.pos = pos; - particle.vel = Quat.FromAngles(Random.Shared.NextSingle() * 360, 0, 0) * Quat.FromAngles(0, Random.Shared.NextSingle() * 360, 0) * Vec3.Forward * 3.0f; + particle.vel = Quat.FromAngles(Noise.u_scalar * 360, 0, 0) * Quat.FromAngles(0, Noise.u_scalar * 360, 0) * Vec3.Forward * 3.0f; particle.ori = Quat.Identity; - particle.scl = (1.0f / 3) * Maths.smooth_start(Random.Shared.NextSingle()); + particle.scl = (1.0f / 3) * Maths.smooth_start(Noise.u_scalar); } }