Hi ,
I would like to make module to generate Perlin Noise but i have some problems with Lua conversion.
This is my class written in Monkey for Perlin Noise which works quite well. I think code is very well documented and is self explanatory but … its not Lua. You can use this code as You like.
This would the the output as example.
http://i53.tinypic.com/2ykzuao.png
http://i53.tinypic.com/2irvi89.png
EDIT: just removed non Lua Code
And this would be Lua version (still buggy)
[blockcode]
– CLASS
– BASIC PERLIN CLASS WITHOUT BITMAP
local sizeX = 640
local sizeY = 480
–first random noise table
local noiseArr = {}
–output table
local terrainArr = {}
–frequency, the lower the larger terrains of same level
local frequency = 1.0
–starting amplitude
local amplitude = 1.0
–change of amplitude of next octave
local persistance = 0.6
–number of octaves
local octaves = 8
–min and max colors
local colMin = {R = 0, G = 0, B = 0}
local colMax = {R = 200, G = 200, B = 200}
– some levels data
local levels = {}
local levelsColorR = {}
local levelsColorG = {}
local levelsColorB = {}
-----------------------------------------==
– just make some data, using fake 2D arrays
--------------------------------------------=
local function new(xx, yy)
sizeX = xx
sizeY = yy
noiseArr = {}
terrainArr = {}
end
– to init perlin noise parameters
local function changeParams(fre, amp, pers, oct)
frequency = fre
amplitude = amp
persistance = pers
octaves = oct
end
--------------------------------------------==
– perlin noise with linear interpolation
--------------------------------------------=
local function LinearFilterNoise(x, y)
local fractionX = x - math.floor(x)
local fractionY = y - math.floor(y)
local x1 = (math.floor(x) + sizeX) % sizeX
local y1 = (math.floor(y) + sizeY) % sizeY
local x2 = (math.floor(x) + sizeX - 1) % sizeX
local y2 = (math.floor(y) + sizeY - 1) % sizeY
if(x1 < 0) then
x1 = x1 + sizeX
end
if(x2 < 0) then
x2 = x2 + sizeX
end
if(y1 < 0) then
y1 = y1 + sizeY
end
if(y2 < 0) then
y2 = y2 + sizeY
end
local finVal = 0
finVal = finVal + fractionX * fractionY * noiseArr[x1 + y1*sizeX]
finVal = finVal + fractionX * (1 - fractionY) * noiseArr[x1 + y2*sizeX]
finVal = finVal + (1 - fractionX) * fractionY * noiseArr[x2 + y1 * sizeX]
finVal = finVal + (1 - fractionX) * (1 - fractionY) * noiseArr[x2 + y2*sizeX]
return finVal
end
– single field noise generation
-----------------------------------------==
local function getRandomNoise(x, y)
local fre = frequency
local amp = amplitude
local finalValue = 0.0
local i
for i = 1, octaves, 1 do
finalValue = finalValue + LinearFilterNoise(x * fre, y * fre) * amp
fre = fre * 2.0
amp = amp * persistance
end
if(finalValue < - 1.0) then
finalValue = -1.0
end
if(finalValue > 1.0) then
finalValue = 1.0
end
finalValue = finalValue * 0.5 + 0.5
return finalValue
end
– create output terrain array
local function MakeTerrainMap()
local x,y
for x = 1, sizeX, 1 do
for y = 1, sizeY, 1 do
terrainArr[x + y * sizeX] = getRandomNoise(x, y)
end
end
end
--------------------------------------------=
– to fill noise array with white noise
--------------------------------------------=
local function InitNoise()
noiseArr = {}
local x,y
for x = 1, sizeX, 1 do
for y = 1, sizeY, 1 do
noiseArr[x + y * sizeX] = (math.random() - 0.5) * 2.0
end
end
end
--------------------------------------------=
– might be usefull, process whole array with sinus
--------------------------------------------==
local function terrainSinus§
local x,y
for x = 1, sizeX, 1 do
for y = 1, sizeY, 1 do
local md = math.sin(y * 180 / sizeY) * 2 - 1
terrainArr[x + sizeX * y] = md * p + terrainArr[x + sizeX * y] * (1.0 - p)
end
end
end
-----------------------------------------==
–
-----------------------------------------==
– just make new data for colour perlin noise
--------------------------------------------=
local function NewColour(xx, yy)
new(xx,yy)
–init levels
local x
for x = 1, 100, 1 do
levels[x] = 0
end
end
– draw image
local function OnRender(scale, dx, dy)
local x,y
for x = 1, sizeX, 1 do
for y = 1, sizeY, 1 do
local val = terrainArr[x + sizeX * y]
local R = colMax.R * val + colMin.R * (1 - val)
local G = colMax.G * val + colMin.G * (1 - val)
local B = colMax.B * val + colMin.B * (1 - val)
–SetColor(R, G, B)
–DrawRect(x * scale + dx, y * scale + dy, scale, scale)
end
end
end
– draw image according to levels, like izolines
local function OnRenderLevel(scale, dx, dy)
local x,y
for x = 1, sizeX, 1 do
for y = 1, sizeY, 1 do
–terrain heigh
local val = terrainArr[x + sizeX * y]*99
–color ID
local val2 = levels[val]
–color itself
local valR = levelsColorR[val2]
local valG = levelsColorG[val2]
local valB = levelsColorB[val2]
–SetColor(val.R, val.G, val.B)
–DrawRect(x * scale + dx, y * scale + dy, scale, scale)
end
end
end
--------------------------------------------==
– start process
--------------------------------------------=
local function OnCreate()
InitNoise()
MakeTerrainMap()
end
--------------------------------------------==
– setup terrain N from lvl min to lvl max
– this is quantization of terrain to one color in range
– this creates area of same value = izo lines
--------------------------------------------=
local function setupLevel(levelMin, levelMax, val, nR,nG,nB)
levelsColorR[val] = nR
levelsColorG[val] = nG
levelsColorB[val] = nB
local x
for x = levelMin, levelMax, 1 do
levels[x] = val
end
end
–EXAMPLE OF USAGE
NewColour(64,48) --to fill screen
changeParams(0.1, 0.99, 0.65, 6) --experiment !!
colMin = {R = 0, G = 50, B = 50} --dark green
colMax = {R = 150, G = 200, B = 150} --light green
setupLevel(1,40,1,0,40,80) --low level water
setupLevel(40,80,2,40,240,40) --medium grass
setupLevel(80,100,3,140,140,0) --high rocks
OnCreate()
[/blockcode]
Bladum [import]uid: 99683 topic_id: 17281 reply_id: 317281[/import]