# 3D Perlin Noise Tutorial

Hello Everyone! My name is paswa!

Today I’m going to be showing you step-by-step on how 3D Perlin Noise can be created and used.

Firstly, we need to understand Perlin Noise! I explained it in a post before this one, you can find it here.

Highly recommended reviewing the Perlin Noise section of the post before progressing this post

Alrighty, assuming you have read up on Perlin noise were gonna start talking about 3D Perlin Noise.

What is 3D Perlin?

3D Perlin Noise is a series/collection of noises along different axis’s. One for each of the x, y, and z axis.

What are the terms your gonna be using?

Density. Density is a number assigned to each pixel within your 3D Perlin noise. Its essentially the equivalent to what color the noise is, but we call it Density since its the collection of multiple noise values.

Here is a small picture resembling 3D Perlin and its colors/densities.

How do we apply this all?

local block_size = 5

local height, width = 30, 100

local blocks = game.Workspace.Blocks

local xOffset = math.random(-100000, 100000)
local yOffset = math.random(-100000, 100000)
local zOffset = math.random(-100000, 100000)

local freq = 2
local ampltiude = 10

local scale = 200

local maxDensity = 0

for x=0, width do
for y=0, width do
if y % 10 == 0 then
end
for z=0, width do
local xP = math.noise(((y + yOffset) / scale) * freq , ((z + zOffset) / scale) * freq) * ampltiude
local yP = math.noise(((x + xOffset) / scale) * freq , ((z + zOffset) / scale) * freq) * ampltiude
local zP = math.noise(((x + xOffset) / scale) * freq , ((y + yOffset) / scale) * freq) * ampltiude

local density = xP + yP + zP
if density >= maxDensity then
local part = Instance.new("Part")
part.Anchored = true
part.Position = Vector3.new(x * block_size, y * block_size, z * block_size)
part.Size = Vector3.new(block_size, block_size, block_size)
part.Parent = blocks
end

end
end
end

This looks like gibberish?
Unless your fluent in Lua you would understand this, I completely don’t expect many of you to fully understand this snippet. Therefore I’ll be explaining portions of this code, mainly ones relating to the topic.

Snippet 1: 3D Perlin Noise

local xP = math.noise(((y + yOffset) / scale) * freq , ((z + zOffset) / scale) * freq) * ampltiude
local yP = math.noise(((x + xOffset) / scale) * freq , ((z + zOffset) / scale) * freq) * ampltiude
local zP = math.noise(((x + xOffset) / scale) * freq , ((y + yOffset) / scale) * freq) * ampltiude

local density = xP + yP + zP

Don’t let the tons of parentheses and math equations get to you, all we need is a basic understanding of how this functions to understand it. First off, please read the past post before progressing as I will not be re-explaining it! Upon finishing it, you will fully grasp this snippet.

Essentially we are combining multiple noise maps (one per axis) into a variable called density, which as we stated earlier is the collection of multiple noise values. This variable is used to alter certain aspects of the noise above, below, or between certain ranges.

if density >= maxDensity then
local part = Instance.new("Part")
part.Anchored = true
part.Position = Vector3.new(x * block_size, y * block_size, z * block_size)
part.Size = Vector3.new(block_size, block_size, block_size)
part.Parent = blocks
end

As said above we just select portions of the noise by limiting/picking certain densities. We then simply place a “block” in that location.

Misc. Snippet

if y % 10 == 0 then
end

I’m sure many of you absolutely do not know what this is or what this does.

Essentially this checks every time the loop runs 10 times and runs the code inside. Which is task.wait(). We use this to yield our generation to allow for more performance on all/lower devices.

% -- Modulo is a math symbol used within lua along with it’s counter partner / -- Division
Modulo is used to return the remainder of divisible value.

For more information on what this does you can visit this website