Noise Of Perlin

How can I create Perlin noise so that there is data for displaying noise in black and white on the smartphone emulator, data for adding your own textures to Perlin noise, and data for creating a specific territory (in pixels) for Perlin noise (for example, an area with 50 by 50 pixels of noise and coordinates of noise on the emulator) in the Corona SDK in lua?

Is this what you are looking for?

1 Like

How to link your texture (images) to different shades of Perlin noise. For example, one texture is assigned to a lighter shade, and another texture is assigned to a darker shade. To get a kind of terrain. Please tell me how I can do this?

Please try to keep the conversation that is about the same topic within the same thread.

I understand the desire to create new threads in the hopes of new/faster replies, but getting answers in community forums may take time.

1 Like

Hi.

I extracted some 2D simplex code of mine and made a little sample using memory bitmaps.

The top two rects use an RGBA bitmap and the bottom two use masks. The right-hand entries are animated.

Here’s the source:

--- Noise example.

--
-- Permission is hereby granted, free of charge, to any person obtaining
-- a copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, sublicense, and/or sell copies of the Software, and to
-- permit persons to whom the Software is furnished to do so, subject to
-- the following conditions:
--
-- The above copyright notice and this permission notice shall be
-- included in all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--
-- [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
--

local memoryBitmap = require("plugin.memoryBitmap")

local CX, CY = display.contentCenterX, display.contentCenterY

local background = display.newRect(CX, CY, display.contentWidth, display.contentHeight)

background:setFillColor(.7)

local DX, DY, W, H = 150, 150, 200, 200

--
--
--

local floor = math.floor
local max = math.max

-- An implementation of Ken Perlin's simplex noise.
--
-- Based on code and comments in [Simplex noise demystified][1],
-- by Stefan Gustavson.
--
-- Thanks to Mike Pall for some cleanup and improvements (and for [LuaJIT][2]!).
--
-- [1]: http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
-- [2]: http://www.luajit.org

-- Index loop when index sums exceed 256 --
local MT = {
	__index = function(t, i)
		return t[i - 256]
	end
}

-- Permutation of 0-255, replicated to allow easy indexing with sums of two bytes --
local Perms = setmetatable({
	151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225,
	140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148,
	247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32,
	57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68,	175,
	74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111,	229, 122,
	60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54,
	65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169,
	200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64,
	52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212,
	207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213,
	119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
	129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104,
	218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241,
	81,	51, 145, 235, 249, 14, 239,	107, 49, 192, 214, 31, 181, 199, 106, 157,
	184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93,
	222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180
}, MT)

-- The above, mod 12 for each element --
local Perms12 = setmetatable({}, MT)

for i = 1, 256 do
	Perms12[i] = Perms[i] % 12 + 1
	Perms[i] = Perms[i] + 1
end

-- Gradients for 2D, 3D case --
local Grads3 = {
	{ 1, 1, 0 }, { -1, 1, 0 }, { 1, -1, 0 }, { -1, -1, 0 },
	{ 1, 0, 1 }, { -1, 0, 1 }, { 1, 0, -1 }, { -1, 0, -1 },
	{ 0, 1, 1 }, { 0, -1, 1 }, { 0, 1, -1 }, { 0, -1, -1 }
}

-- 2D weight contribution
local function GetN (ix, iy, x, y)
    local t = .5 - x^2 - y^2
    local index = Perms12[ix + Perms[iy + 1]]
    local grad = Grads3[index]

    return max(0, t^4) * (grad[1] * x + grad[2] * y)
end

-- 2D skew factor:
local F = (math.sqrt(3) - 1) / 2
local G = (3 - math.sqrt(3)) / 6
local G2 = 2 * G - 1

--- 2-dimensional simplex noise.
-- @number x Value #1...
-- @number y ...and #2.
-- @treturn number Noise value ∈ [-1, +1].
local function SampleNoise (x, y)
    -- Skew the input space to determine which simplex cell we are in.
    local s = (x + y) * F
    local ix, iy = floor(x + s), floor(y + s)

    -- Unskew the cell origin back to (x, y) space.
    local t = (ix + iy) * G
    local x0 = x + t - ix
    local y0 = y + t - iy

    -- Calculate the contribution from the two fixed corners.
    -- A step of (1,0) in (i,j) means a step of (1-G,-G) in (x,y), and
    -- A step of (0,1) in (i,j) means a step of (-G,1-G) in (x,y).
    ix, iy = ix % 256, iy % 256

    local n0 = GetN(ix, iy, x0, y0)
    local n2 = GetN(ix + 1, iy + 1, x0 + G2, y0 + G2)

    --[[
        Determine other corner based on simplex (equilateral triangle) we are in:
        if x0 > y0 then
            ix, x1 = ix + 1, x1 - 1
        else
            iy, y1 = iy + 1, y1 - 1
        end
    ]]
    local xi = x0 > y0 and 1 or 0
    local n1 = GetN(ix + xi, iy + (1 - xi), x0 + G - xi, y0 + G - (1 - xi))

    -- Add contributions from each corner to get the final noise value.
    -- The result is scaled to return values in the interval [-1,1].
    return 70.1480580019 * (n0 + n1 + n2)
end

--
--
--

do
	local bitmap = memoryBitmap.newTexture{ width = W, height = H }

	for y = 1, bitmap.height do
		for x = 1, bitmap.width do
			local gray = SampleNoise(x, y)

			bitmap:setPixel(x, y, gray, gray, gray, 1)
		end
	end

	local image = display.newImageRect(bitmap.filename, bitmap.baseDir, W, H)

	image.x, image.y = CX - DX, CY - DY
end

--
--
--

do
	local bitmap = memoryBitmap.newTexture{ width = W / 2, height = H / 2 }
	local image = display.newImageRect(bitmap.filename, bitmap.baseDir, W, H)

	timer.performWithDelay(120, function(event)
		local delta = 15 * math.sin(event.count * 20) -- something that changes

		for y = 1, bitmap.height do
			for x = 1, bitmap.width do
				local gray = SampleNoise(x + delta, y - delta)

				bitmap:setPixel(x, y, gray, gray, gray, 1)
			end
		end

		bitmap:invalidate()
	end, 0)

	image.x, image.y = CX + DX, CY - DY
end

--
--
--

local function RoundUpMask (x)
	local xx = x + 13 -- 3 black pixels per side, for mask, plus 7 to round
					  -- all but multiples of 8 past the next such multiple
	return xx - xx % 8 -- Remove the overshot to land on a multiple
end

local PixelW, PixelH = RoundUpMask(W), RoundUpMask(H)

--
--
--

do
	local bitmap = memoryBitmap.newTexture{ format = "mask", width = PixelW, height = PixelH }

	for y = 4, bitmap.height - 3 do
		for x = 4, bitmap.width - 3 do
			bitmap:setPixel(x, y, SampleNoise(x, y))
		end
	end

	local rect = display.newRect(CX - DX, CY + DY, W, H)

	rect:setFillColor(1, 0, 0)

	local mask = graphics.newMask(bitmap.filename, bitmap.baseDir)

	rect:setMask(mask)
end

--
--
--

do
	local bitmap = memoryBitmap.newTexture{ format = "mask", width = PixelW, height = PixelH }

	timer.performWithDelay(120, function(event)
		local delta = 25 * math.sin(event.count * 30) -- something that changes

		for y = 4, bitmap.height - 3 do
			for x = 4, bitmap.width - 3 do
				bitmap:setPixel(x, y, SampleNoise(x - delta, y + delta))
			end
		end

		bitmap:invalidate()
	end, 0)

	local rect = display.newRect(CX + DX, CY + DY, W, H)

	rect:setFillColor(0, 0, 1)

	local mask = graphics.newMask(bitmap.filename, bitmap.baseDir)

	rect:setMask(mask)
end

and the build settings:

settings =
{
	android =
	{
	--        versionCode = "3"
	},

	orientation =
	{
			default = "landscape"
	},

	plugins = {
		["plugin.memoryBitmap"] = { publisherId = "com.coronalabs" }
	},

	excludeFiles =
    {
        -- 
        all = { "doc.css", "*.md", "config.ld" },

        -- Exclude all Android icon files and .ogg files
		-- TODO: Filter out auxiliary Android databases; needs some naming convention (right now, seems to be either root-level or ending in "_assets"?)
        iphone = { "Icon-*dpi.png", "*.ogg" },

        -- Exclude iOS "retina" image files and .m4a files
		-- TODO: Filter out images, etc. that would get incorporated into the database (mentioned above for iphone); again, needs naming convention
        android = { "Icon.png", "*@2x.png", "*.m4a" } 
    }
}

I have some other stuff like shader mixins but am about dead on my feet so will leave it there for now. :slight_smile:

3 Likes

Okay. noise with pixels is good. But how to link my png images to this texture, or upload images to textures. Because I can change the colors of pixels, it was fun with your example about noise. I’ve read a lot: plugin about “memoryBitmap”, “Graphics/Audio/Animation” from “Developer Guides”, “newTexture” from “memoryBitmap” and “Texture Loading/Management” from “Developer Guides ▸ Graphics/Audio/Animation”. I looked at various examples. I tried to substitute the name of my image under “filename”, namely “ground1.png” with and without these double quotes, and in the end I was given that the variable (in the case of your example) bitmap, has a zero value. So please explain how I can upload my images to textures and in noise to get a “noise” texture terrain. And how me can get certain intervals of shades of noise color out of the noise Perlin. To add your own images to these intervals of shades to generate the terrain. :pray: :pray: :pray:
It is advisable to explain to me how and where to add a group, so that when you move the resulting map of the area, move it using the buttons. For there the map does not consist of a single image. There is earth, stone, soil, water, and for each its own picture in png format

Once you’ve generated your perlin noise you then use that to draw your terrain. I use perlin to seed a map with values from 0 to 1. Values under 0.4 are water, values above this define the land height.

I then enhance this with a river algo to make a more realistic landscape.

What kind of data from the noise you take and how exactly, in which place of the code you fill the area with values from 0 to 1. And what is “river algo”, for the realism of the landscape. Please provide a sample code. Because I’ve tried a lot, but it doesn’t work out. :confused: :pensive:

If you follow the link in discord it explains it very well.

Pasting here for others - https://www.redblobgames.com/maps/terrain-from-noise/

1 Like