OpenSimplex Noise in Lua!

This might prove useful to some who are looking to use Perlin noise in their game.
You can find the full documentation for it in here. This is but a translation from Java to Lua. (2S)

To start using it, you need to seed the generator first. To do so, use the .Seed function and pass any number in the interval [-2²⁴, 2²⁴-1]¹

After you have decided the dimensions that you are going to use, refer to this list: (Comments are directly copied from the source)

// 2D (x,y)
Classic2D  // 2D SuperSimplex noise, standard lattice orientation.
XBeforeY2D // 2D SuperSimplex noise, with Y pointing down the main diagonal. Might be better for a 2D sandbox-style game, where Y is vertical. Probably slightly less optimal for heightmaps or continent maps.

// 3D (x,y,z)
Classic3D // 3D Re-oriented 8-point BCC noise, classic orientationProper substitute for what 3D SuperSimplex "should" be, in light of Forbidden Formulae. Use noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate.
XYBeforeZ3D // 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Y). Recommended for 3D terrain and time-varied animations. The Z coordinate should always be the "different" coordinate in your use case. If Y is vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use noise3_XZBeforeY. If Z is vertical in world coordinates, call noise3_XYBeforeZ(x, y, Z). For a time varied animation, call noise3_XYBeforeZ(x, y, T).
XZBeforeY3D // 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Z). Recommended for 3D terrain and time-varied animations. The Y coordinate should always be the "different" coordinate in your use case. If Y is vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). If Z is vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use noise3_XYBeforeZ. For a time varied animation, call noise3_XZBeforeY(x, T, y) or use noise3_XYBeforeZ.

// 4D (x,y,z,w)
Classic4D // 4D SuperSimplex noise, classic lattice orientation.
XYBeforeZW4D // 4D SuperSimplex noise, with XY and ZW forming orthogonal triangular-based planes. Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. Recommended for noise(x, y, sin(time), cos(time)) trick.
XZBeforeYW4D // 4D SuperSimplex noise, with XZ and YW forming orthogonal triangular-based planes. Recommended for 3D terrain, where X and Z (or Y and W) are horizontal.
XYZBeforeW4D // 4D SuperSimplex noise, with XYZ, oriented like Classic3D, and W for an extra degree of freedom. Recommended for time-varied animations which texture a 3D object (W=time)
Performance

Since the number of calculations is dependent on the seed and the arguments passed, these results are just for reference.

Over 1 million iterations²:

math.noise   : 0.1576760999742
Classic2D    : 0.7802108000032
XBeforeY2D   : 0.7668126000207
Classic3D    : 1.1891150000156
XYBeforeZ3D  : 1.2091178999981
XZBeforeY3D  : 1.2586106999952
Classic4D    : 2.4105452000222
XYBeforeZW4D : 2.5011013000039
XZBeforeYW4D : 2.5405165000121
XYZBeforeW4D : 2.5745853999979
Notes

¹It is actually possible to use numbers not within the interval, but be warned as I am pretty sure that it doesn’t return many different maps. i.e. you get the exact same value even for different seed.

²Tested on an underclocked i7-6700 (3.20GHz) and 2133 Mhz RAM. The reference to the function is also cached. I picked the highest number after changing the seed a few times.

To get it, run

local s=game:GetObjects'rbxassetid://6526664486';s[1].Parent=game;game.Selection:Set(s)

or if it fails, click here and get the module.

13 Likes

wow this looks very useful, perfect timing as I was just about to test with terrain generation

1 Like