This is a fairly straight-forward implementation of Kurt Spencer's OpenSimplex Noise (original Java implementation). I started this project intending to build a simplex noise generator but then I remembered that Ken Perlin is a patent troll.
- The root LCG might require a license. I did a bunch of research about this. Given that OpenSimplex actually had to be created, I think it's important to maintain provenance. The constants used in OpenSimplex's linear congruential generator come from Donald Knuth's MMIX implementation (although searching "6364136223846793005l" yields Minecraft code and threads about OpenSimplex; the
long
suffix dramatically reduces the results). Given that it's on Wikipedia (and in Minecraft), I'm going to assume the numbers themselves are not licensed. If you're not comfortable making that assumption, I'll (eventually) add support to change the LCG (or you can make a PR with open source constants, which would be pretty neat). - External libraries possibly necessary. JavaScript doesn't handle 64-bit integers natively. I might look at 32-bit generator later. I've got
Bluebird
in the production dependencies for now because I'd like to includeBluebird
(Promise
with.finally
and sequential execution via.each
) support eventually, but I might also strip it. We'll see.
This is just until it's published.
npm install --save git+https://github.com/wizardsoftheweb/opensimplex-noise
TODO: write documentation after the API is done
If you're desparate (as in "completely desparate and have absolutely no other option because your life depends on generating the docs for this repo you found on the internet"), you can build them via npm
:
npm run build:docs
Chances are it's not going to work as intended. TypeDoc's got an issue with configuration and I lost all motivation to fix this repo's config after figuring out the bug upstream.
I've tried to pull out specific sections of the original to compare against the TypeScript versions, in part to see where the TypeScript might need improvement.
npm run benchmark
-
The benchmarks require Java, i.e.
which javac # some non-empty path which java # some non-empty path
For testing, I've been using
openjdk-8-jdk
onUbuntu 16.04.2 LTS
viaWindows 10 Pro
. I will eventually move this out of my gaming environment and into my work environment so that I can run real comparisons, but that's far enough in the future I'm not even including it in the roadmap. Yet. -
Benchmarks are slightly silly. Your benchmark is going to be different than mine. Don't use the results as objective proof of superiority, because they're not. I'm an average coder writing in a transpiled interpreted language not built to handle
long
s natively, so you should expect the Java version to run better. However, Java is an interpreted language, so this code could be occasionally faster. -
For the most part, the TypeScript hasn't been optimized. I have no doubt there's a ton of inefficient code slowing things down.
-
I tried to make things one-to-one. For example, while comparing the LCG initialization, I run this TypeScript:
const lcgSequence = new SequenceFromLcg64(0); for (let index = 0; index < PermutationArray.NUMBER_OF_LCG_INIT_STEPS; index++) { lcgSequence.step(); }
against this Java:
long seed = 0L; seed = seed * 6364136223846793005l + 1442695040888963407l; seed = seed * 6364136223846793005l + 1442695040888963407l; seed = seed * 6364136223846793005l + 1442695040888963407l;
In general, I usually gave Java the benefit of the doubt when it came to slimming the code down.
I wanted to build this myself before using libraries to get a better understanding of the process. I have several applications that require a solid n
-dimensional noise generator. Simplex noise provides smoother, more controllable noise than, say, diamond-square, and has the added benefit of sounding really pretentious. It's also anecdotally the gold standard and mathematically pretty neat.
However, simplex noise is under a pretty nasty patent. Like, really nasty. I don't support patenting algorithms. If the history of math has taught us anything, it's that someone smarter will come along and redo your work except better. For that reason, I decided to play with OpenSimplex Noise, which does basically the same thing using a slightly different set of tools. It's slower, so I'll eventually add some benchmarks to illustrate that.
I highly doubt this will see much production beyond a couple of hobby projects. I'm building it primarily to be able to debug other implementations when I break them.
These percentages are pretty arbitrary. Today's 47% could be tomorrow's 90% or vice versa.
Once all of these are finished, I'll release v1
. Until then, v0
should be used with caution, because it's not stable.
Progess | Feature |
---|---|
2% | Port OpenSimplexNoise.java |
10% | Break down OpenSimplexNoise.java into constituent tasks |
100% | Build and document an implementation of the LCG used in OpenSimplexNoise.java |
100% | Duplicate the LCG's output (and long manipulation) |
100% | Duplicate the [0, 255] permutation for 2D, 3D, and 4D |
20% | Benchmarks against Java version |
0% | Publish package on npm |
0% | Switch defaults (branch, badges) from master to dev |
80% | Add fancy README TOC |
These are things I'd like to add, but probably won't be included in v1
. If not, they'll most likely constitute one or more minor version increments.
Progess | Feature |
---|---|
0% | Find FOSS linear congruential generator parameters. |
0% | Break out LCG code into its own repo |
0% | Implement reverse LCG |
0% | Tests against the original Java |
0% | Determine Bluebird usage or move it to devDependencies |
0% | Fix TypeDoc config |
0% | Greenkeeper (or similar) integration |