Simplex Noise Module

Hello developers! I’ve been working on this for the past few days now and I think I’m about ready to put out a released version of this. This is a fully self-contained implementation of the Simplex Noise algorithm as popularized by Ken Perlin, all in Lua no less. It offers much more customization than the standard Roblox math.noise functionality, as you can initialize Octave objects with their own respective seeds. This version currently offers 2D and 3D evaluation, both scaled to be in the [-1,1] range. If you’re interested in the module you can grab a copy of it here:

Module Download

Here’s an example of a terrain map I generated using this algorithm and my marching cubes implementation:

Implementation
A standard use of this module will generally look like this:

local Simplex = require(script.SimplexModule)

local Octave = Simplex() --Here you can provide a seed value, although one is not required
--If no seed is provided, a random seed is generated instead.

Octave:Init() --Must be called to initialize the octave

for x = 1,10 do
  for y = 1,10 do
    local Noise2D = Octave:Get2DValue(x,y) -- Retrieve a value from a 2D point
    for z = 1,10 do
      local Noise3D = Octave:Get3DValue(x,y,z) -- Retrieve a value from 3D point
    end
  end
end

Performance Evaluation
Now, enough about the code, how does it stack up performance wise?
Here are the current benchmarks:

  0.23782290000236 -- My Module
  0.032688800012693 -- math.noise

These benchmarks are for the 2D implementation of the module. The 3D version suffers almost 1.5 times worse in comparison.

So yeah… the performance is not the best. this is mostly due to a few factors: bit manipulation is too expensive, to the point where modulo was actually faster (somehow…), and this is Lua. Lua isn’t nearly as fast as the C-side implementation of math.noise although Roblox if you read this a simplex noise module would be pretty sweet y’know?

Use Cases
Anyways, if you’re thinking about using this for a procedural or real-time use case, I would highly advise using math.noise instead, as the performance benefits far outweigh the visual improvements and versatility. However, I would say this is very well suited for something like a plugin or single-use implementation, where performance is not the utmost priority.

Thank you for reading, and I hope this module provides something for you! Until next time!

40 Likes

Kinda confused why you wouldn’t use perlin noise.

Simplex noise offers more detail and that is that.

Simplex noise has benefits over perlin:

  1. Simplex uses a non-standard grid system (Known as a simplical grid) This means that the grid appears less grid-like and seems more random overall.
  2. Simplex is actually slightly faster than perlin, although math.noise is faster because it’s a C-side implementation.
  3. Simplex can be generalized to higher dimensions much. MUCH easier, with a much lower performance drop off as compared to perlin noise

If you’re asking why I made my own module instead of using math.noise, I stated the reason in my original post. math.noise in Roblox doesn’t allow you to generate a new map, it uses the same perlin map every single time, so there’s no real difference. my module allows you to generate completely new simplex maps, and operate with them independently.

8 Likes

I see. I like perlin as you can load back your map but whatever floats your boat

Well you can specify a seed for my module aswell. There’s no need to use a random seed everytime. see the implementation section and check the comments. If you provide the same seed you get the same map every time

3 Likes

Can you post the source in Github/Pastebin?

image

1 Like

Sorry about that! Apparently I published it as a package. I switched it over to an uncopylocked asset and republished it. The link should take you to a copyable version of the object. I won’t make a github for this right now, it’s not a large enough codebase to warrant it at the moment.

3 Likes

Roblox should consider adding their own simplex function as getting satisfying results with math.noise requires weird and often hacky methods.

I was actually working on a procedural terrain which doesn’t have to be very fast, so this will come in useful.

8 Likes

How is this implementation different from Perlin’s implementation? Perlin has Simplex Noise patented, so there could be some potential legal issues with this system. I doubt that it’ll be present but potential legal problems are more than enough to convince me to not use the module.

Reading the patent information and looking at a few sources online, it states that the patent is only applicable to situations involving generation of images/textures.

EDIT: To clarify, under the claims section, every claim is only stated in the context of generating digital images. That’s what I mean when I say the patent only applies to image generation

1 Like

What is the output range for the values? By running million iterations on random seeds 10x, I got approximately (-1.06916716, +1.06916715).

every noise function has that kind of issue. Even math.noise will give you the occasional -1.025 and 1.049. It is normalized to return values as close as possible to the -1,1 space, but inherently there will be outliers.

Simplex noise is great for avoiding some of the artefacts found in perlin noise.
It works out better for terrain generation as you get more “uniformity” across all directions.
Great release!
My only suggestion is for a potential future implementation of open simplex noise to avoid the patent.

3 Likes

Nice build! this offers a lot of opportunities instead of math.noise, and it looks way more natural.:+1:

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀Here’s an example:
⠀⠀⠀Math.noise()⠀⠀⠀⠀⠀Simplex Noise Module
⠀⠀⠀⠀⠀


x2⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

x3⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

As shown above, math.noise exceeds it’s range(in red), while the marching squares method does not exceed it’s range at all. The Simplex Module got very close to the boundary, but it never poked through. Additionally, as seen on x2 and x3, it forms noticeable ridges that follow each other.

7 Likes