Skip to content

Instantly share code, notes, and snippets.

@psema4
Created August 12, 2021 21:26
Show Gist options
  • Save psema4/bee2614208944f08f5c4640ff582c611 to your computer and use it in GitHub Desktop.
Save psema4/bee2614208944f08f5c4640ff582c611 to your computer and use it in GitHub Desktop.
An implementation of the Squirrel3 Noise-based RNG
// Based on the GDC 2017 talk "Math for Game Programmers: Noise-Based RNG"
// https://www.youtube.com/watch?v=LWFzPP8ZbdU&ab_channel=GDC
const BIT_NOISE1 = 0xB5297A4D
const BIT_NOISE2 = 0x68E31DA4
const BIT_NOISE3 = 0x1B56C4E9
const PRIME1 = 198491317
const PRIME2 = 6542989
class Squirrel3 {
constructor() {
}
// get1d(), get2d() and get3d() each return an integer
get1d(x=0, seed=0) {
let mangled = x
mangled *= BIT_NOISE1
mangled += seed
mangled ^= (mangled >> 8)
mangled += BIT_NOISE2
mangled ^= (mangled << 8)
mangled *= BIT_NOISE3
mangled ^= (mangled >> 8)
return mangled
}
get2d(x=0, y=0, seed=0) {
return this.get1d(x + (PRIME1 * y), seed)
}
get3d(x=0, y=0, z=0, seed=0) {
return this.get1d(x + (PRIME1 * y) + (PRIME2 * z), seed)
}
// get1df(), get2df() and get3df() each return a float between 0 and 1
// (assumes we're working with int32's)
get1df(x=0, seed=0) {
return this.get1d(x, seed) / 0xFFFFFFFF
}
get2df(x=0, y=0, seed=0) {
return this.get2d(x, y, seed) / 0xFFFFFFFF
}
get3df(x=0, y=0, z=0, seed=0) {
return this.get3d(x, y, z, seed) / 0xFFFFFFFF
}
}
@trevorjay
Copy link

trevorjay commented Apr 21, 2025

This needs to account for the fact that Javascript treats all bitwise arguments as signed, not unsigned as the original C does. As a result, the range of the returned numbers is cut in half to 0 - 0xFFFF. To account for this, you need to use either use the unsigned version of shift (>>>) or convert back to unsigned after each operation (the easiest way to do so being >>> 0). There may be other issues, but this was good enough of a fix for my purposes:

mangled *= BIT_NOISE1
mangled += seed
mangled ^= (mangled >>> 8) 
mangled >>>= 0
mangled += BIT_NOISE2
mangled ^= (mangled << 8) >>> 0
mangled >>>= 0
mangled *= BIT_NOISE3
mangled ^= (mangled >>> 8) 
mangled >>>= 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment