• Subject: Simplex noise (2D and 3D) with the LuaJIT FFI
• From: Steven Johnson <steve@...>
• Date: Tue, 22 Feb 2011 17:09:31 -0600

```Hello all. Joining the FFI bandwagon here.

I started with the code in "Simplex noise demystified" [1] and made a
fairly mechanical translation of it to Lua, thus far to the 2D and 3D
cases.

This by itself was already pretty fast with LuaJIT, and I gained a
little more here and there with some basic ctypes.

I got this down quite a bit further after eliminating a "NYI: register
coalescing too complex" case, via some bit tricks, herein poorly
described: There is a nested "if-elseif-else" for choosing the simplex
indices' offsets, based on some comparisons of one corner's x, y, and
z to one another. Each such offset can be classified according to
which comparisons produce it. It is then a matter of converting the
resulting logical operations to their bitwise counterparts, then
substituting the sign bits from each comparison for true, or lack of
bits for false.

Given a 5000x5000 sample grid for 2D simplex noise, and a 100x100x100
grid for 3D, and searching for the minimum and maximum values, I get:

Average, 2D: .000000166 s
Average, 3D: .000000298 s
4.439 seconds total

on my laptop (Core 2 Duo, 2 GHz), and

Average, 2D: .000000044 s
Average, 3D: .000000088 s
1.27 seconds total

on another machine (Core i7: 2.67 GHz, 2.79 Ghz).

In each case, I get minimum and maximum of (-.839583, .819512) for 2D
and (-.954013, .954013) for 3D. From printouts the results appear to
agree, up to at least the thousandths place, with Gustavson's results
for sample values of x, y, z I've tried between -50 and +50.

The code is a bit horrible-looking at the moment. :D It shows most
things I tried, sans vector types and maybe one or two more things.

I've been testing this embedded, so apologies if the print()/printf()
needs fixing. It's also tied to the endian-ness at the moment. :(

Also, Mike: If I call SignBit() in Simplex3D (commented out in the
code) instead of inlining its body, I get rather different results:
something like (-168, 168) for the minimum and maximum. Am I
overlooking anything here? This is raw beta 6, no patches.

-------------------------------------------------------------------------------------

Code (such as it is) is submitted to the public domain: MIT if
possible, more restrictive license if the
source demands (I didn't see anything, though I mailed the author).
Improvements welcome.

[1] - http://webstaff.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
```

Attachment: Noise.lua
Description: Binary data

• Follow-Ups: