Help fixing a Noise Function!

Can anyone find anything wrong with the noise function code below? As the following image shows, the noise seems to flatten out after the y loop passes 22 or 23. The bitwise.bit_xor function is from Carlos’ “bitwise operators in lua” module posted on the code exchange here: http://developer.anscamobile.com/code/bitwise-operators-lua

My code:

[lua]–Initialization
display.setStatusBar( display.HiddenStatusBar )
local bitwise = require “bitwise”

local n
local function noise(x, y)
n = x + y * 47
n = bitwise.bit_xor(n * math.pow(2, 13), n)
n = (n * (n * n * 15731 + 789221) + 1376312589)
n = n % 2147483648
n = n / 1073741824
n = 1 - n
–n = ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) % 2147483648) / 1073741824.0)
return n
end

local squares = {}
for x = 1, 100, 1 do
squares[x] = {}
for y = 1, 100, 1 do
squares[x][y] = display.newRect(x * 5 - 5, y * 5 - 5, 5, 5)
squares[x][y]:setFillColor(noise(x, y) * 100)
end
end[/lua]

The output mysteriously settles to “1” after a short while:

Image and video hosting by TinyPic [import]uid: 99903 topic_id: 24697 reply_id: 324697[/import]

Your n gets too large for any meaningful operations. Use smaller primes and you’ll have a beautiful block of noise.

local function noise(x, y)  
 local n  
 n = x + y \* 47  
 n = bitwise.bit\_xor(n \* math.pow(2, 13), n)  
 n = (n \* (n \* n \* 7 + 41) + 29)  
 n = n % 2147483648  
 n = n / 1073741824  
 n = 1 - n  
 return n  
end  

All the noise function is is a random number generator that gives the same results every time. The results aren’t much different to:

math.randomseed(os.time())  
local \_random = math.random  
for x = 1, 100, 1 do  
 squares[x] = {}  
 for y = 1, 100, 1 do  
 squares[x][y] = display.newRect(x \* 5 - 5, y \* 5 - 5, 5, 5)  
 squares[x][y]:setFillColor( \_random(0,255) )  
 end  
end  

Don’t know what you’re after. [import]uid: 44647 topic_id: 24697 reply_id: 100183[/import]

Thanks toby! That was a very helpful answer. Now at least I have some idea where the problems are coming from. Unfortunately, when increasing the array size to 1000 x 700, I run out of noise yet again, and those new primes you suggested can’t get much lower.

Image and video hosting by TinyPic

I need to generate pseudo-random numbers for realtime perlin noise generation over game levels of arbitrarily large sizes. So, the random generator has to function properly no matter how large x or y become(within reasonable limits). The bare minimum level size I’m working towards is 3000 x 1000. It is possible to very quickly fill a 3000 x 1000 array with random values using a saved seed and the second code block you posted- I wrote something similar- but the problem I run in to in that case is memory usage. A 3000x1000 array takes 36MB of memory, even if each value is limited to 0 or 1. I have yet to find a way to specify data types. I need a dozen or more 3000x1000 arrays containing unique randoms to each other to generate multiple fields of perlin noise. I have found that I can simply combine ten different randoms into a long number and then extract them using math.ceil and multiplication and division, but all this adds more and more CPU time to what has to be a realtime process.

If I can only get this noise function working *just right,* it will simplify everything. Each part of the level can simply access the same random used by the others by sending the same x and y value. I won’t have to worry about combining numbers, saving enormous arrays to memory, and then splitting the numbers.

Alternatively, if I could find a way to limit the arrays to arrays of bytes, each array would only take a few MB. If I could specify bits, each array would take a few hundred KB. I could use multiple arrays instead of using expensive mathematical trickery to combine them into one.

I’ll keep working the problem, of course. If you happen to know of any obvious solutions, I’d love to hear them.

Thanks. [import]uid: 99903 topic_id: 24697 reply_id: 100219[/import]

Alright, I’ve more or less solved the problem re endless x and y values.

[lua]local n
local xSeed = 0
local ySeed = 0
local function noise(x, y)
y = y + ySeed
if y > 100 then
y = y % 100
end
x = x + xSeed
if x > 500 then
x = x % 500
end
n = x + y * 71
n = bitwise.bit_xor(n * math.pow(2, 13), n)
n = (n * (n * n * 7 + 47) + 29)
n = n % 2147483648
n = n / 1073741824
n = 1 - n
return n
end

local squares = {}
for x = 4500, 5000, 1 do
squares[x] = {}
for y = 3000, 3350, 1 do
squares[x][y] = display.newRect((x - 4500) * 2 - 2, (y - 3000) * 2 - 2, 2, 2)
squares[x][y]:setFillColor(noise(x, y) * 100)
end
end[/lua]

The xSeed and ySeed values don’t really change the noise other than shifting it around. The repeating pattern evident in the newest screenshot below stays the same. I’d love for a way to easily, truly change the random pattern rather than shifting it.

Anyone looking to use this noise function should keep in mind that it is quite a bit slower than math.random(). In fact it is so slow that I might combine multiple enormous arrays after all. Once again, specifying data types would solve this problem. I thought I was on the verge of a breakthrough when I tried filling an array with True or False, but the boolean value for True somehow requires as much space as numbers nine digits or larger.

Image and video hosting by TinyPic [import]uid: 99903 topic_id: 24697 reply_id: 100340[/import]

Hey, having a little bit of fun with this over here. Cooked up this reasonably inefficient block of code using sqlite to generate all the random bits you could want.

[lua]print(os.time())
display.setStatusBar( display.HiddenStatusBar )
local sqlite3=require(“sqlite3”)
local db = sqlite3.open_memory()
local bits
for row in db:nrows(“SELECT hex(randomblob(375000)) AS blob”) do
bits=row.blob
end
db:close()

local squares = {}

local count = 1
local function noise()
local b = bits:sub(count, count+1)
count=count+2
return tonumber(b,16)
end

for x = 4500, 5000, 1 do
squares[x] = {}
for y = 3000, 3350, 1 do
squares[x][y] = display.newRect((x - 4500) * 2 - 2, (y - 3000) * 2 - 2, 2, 2)
squares[x][y]:setFillColor( noise() )
end
end

print(os.time())[/lua] [import]uid: 44647 topic_id: 24697 reply_id: 100611[/import]

Will, this got me looking into databases for storing my arrays, but they proved too slow for my needs. This trick of yours using a database command to generate an enormously long string of hex data came so close to being useful though! It turns out that very long strings on the order of 3,000,000 characters do not take up much memory at all. They also save and load to and from files very quickly. However the “randomblob” SQL command can not be seeded as far as I can tell.

Saving the output from a hex(randomblob(3000000)) takes 6MB of storage, and I would need ten or so for each level. So, while the memory situation is great, it is not useable unless the random output can be seeded. I need to be able to come to the same random values again and again between game sessions. If you know of a way to seed it, I’d love to know.

Using very long strings suddenly becomes next to impossible without randomblob filling them. I tried using a very long loop to concatenate random values onto the string and reproduce the overall effect of randomblob, but doing so takes forever. If you know of a way to very quickly fill a string with SEEDED random characters, that would be fantastic. [import]uid: 99903 topic_id: 24697 reply_id: 101037[/import]