Perlin Noise Tree

I have a Perlin Noise code it works awesome except the trees. The trees don’t work for some reason.

The Code
local Part = Instance.new("Part") --For cloning
Part.Anchored = true
Part.FormFactor = "Custom"
Part.Size = Vector3.new(4,4,4)
Part.TopSurface = "Smooth"  
Part.BrickColor =  BrickColor.Green()

local seed = math.random(1, 10e6)
local frequency = 3
local power = 10
local resolution = 100 

local WaterLevel = 0 --We store the level the water spawns below

for x = 1, resolution do  
	for z = 1, resolution do
        local y1 = math.noise(
            (x*frequency)/resolution,
            (z*frequency)/resolution,
            seed
        )

		local y2 = math.noise(
            (x*frequency*.125)/resolution,
            (z*frequency*.125)/resolution,
            seed
		)
		
		local y3 = math.noise(
            (x*frequency*4)/resolution,
            (z*frequency*4)/resolution,
            seed
        )
        
		local y = (y1*y2*power*power)+y3
		
        local Part = Part:Clone()
        Part.Parent = game.Workspace.Map
        Part.CFrame = CFrame.new(x,y,z)
		
		if z%resolution/2==resolution/4 then
			wait(0)
		end
		
		--[[if math.abs(y2) < .1 then
		    Part.BrickColor = BrickColor.Green()
		elseif math.abs(y2) > .25 then
		    Part.BrickColor = BrickColor.Red()
		else
			Part.BrickColor = BrickColor.Blue()
		end]]
		
		if y+(Part.Size.Y/2)<WaterLevel then -- We check if water is able to spawn.
			local WaterPart=Part:Clone()
			WaterPart.CanCollide=false -- We set some values to the water.
			WaterPart.Transparency=1
			WaterPart.Reflectance=0.1
			WaterPart.Size=Vector3.new(4,WaterLevel-y+(Part.Size.Y/2),1)
			WaterPart.BrickColor=BrickColor.new("Cyan")
			WaterPart.CFrame=CFrame.new(x,y+(WaterLevel-y+(Part.Size.Y/2))/2,z)
			WaterPart.Parent=workspace.Map
			game.Workspace.Terrain:FillBlock(WaterPart.CFrame, WaterPart.Size, Enum.Material.Water)
		end
		
		local c = 0.4 -- c is some constant you use to customise how the noise feels
		local threshold = 0.3  -- the TreeChance needs to be greater than this to spawn a tree
		
		
		local TreeChance = math.noise(x * frequency * c / resolution, z * frequency * c / resolution, seed)
		
		
		if TreeChance > threshold then
			local Tree = game.Workspace.Tree:Clone()
			local TreeHeight = Tree.Size.Y
			local PartHeight = Part.Size.Y
			local TreeY = y + PartHeight / 2 + TreeHeight  / 2
  		  	Tree.Parent = workspace.Map
   			Tree.CFrame = CFrame.new(x,TreeY,z)
		end
		
	end
end
The Tree Bug

Note: That flying tree is not a bug. The bug is that the trees are next to eachother

1 Like

you should probably change the x and z coordinates

Ok, I realised the mistake. What the tree generation is doing is placing a tree on every block that is covered by the noise generated. What you want to do is one of 2 things: if you are using biomes, and only want trees to spawn in the forest biome defined by the TreeChance noise, you would do this:

local c = 0.4 -- c is some constant you use to customise how the noise feels
local threshold = 0.8  -- This defines how dense the trees are (how close together, lower = more dense) [between 0 and 1]
local NoiseThreshold = 0.5  -- This defines the size of the biome (lower = bigger) [between 0 and 1]
			
			
local TreeNoise = math.noise(x * frequency * c / resolution, z * frequency * c / resolution, seed) + 0.5
local TreeChance = math.random()
			
if TreeNoise > NoiseThreshold and TreeChance > threshold then
	local Tree = game.Workspace.Tree:Clone()
	local TreeHeight = Tree.Size.Y
	local PartHeight = Part.Size.Y
	local TreeY = y + PartHeight / 2 + TreeHeight  / 2
	Tree.Parent = workspace.Map
	Tree.CFrame = CFrame.new(x,TreeY,z)
end

If you do not want biomes at all, and just want trees to spawn on every block, simply replace the noise with a math.random, like so:

local threshold = 0.8  -- This defines how dense the trees are (how close together, lower = more dense) [between 0 and 1]

local TreeChance = math.random()

if TreeChance > threshold then
	local Tree = game.Workspace.Tree:Clone()
	local TreeHeight = Tree.Size.Y
	local PartHeight = Part.Size.Y
	local TreeY = y + PartHeight / 2 + TreeHeight  / 2
	Tree.Parent = workspace.Map
	Tree.CFrame = CFrame.new(x,TreeY,z)
end

Aslo, a side note, you might want to put the tree generation in the else part of the if statement when checking to add water, because you don’t want trees to be added underwater.

2 Likes

I think you need to change this:

TreeChance = TreeChance * n

Where n is a big number. This is because Perlin noise returns a number between -.5 and .5 iirc. And the previous value and the next values will be very close to each other. So try making they far apart instead.

1 Like

he cant use a math.random() because if he does, then the tree spawning wont be the same every time with the same seed unless he uses math.randomseed()

1 Like

Perlin noise returns a value between -0.5 and 0.5 **when using fractional values for x, y and z (credit to @vtaetwrjxvdpgwjqkfzw for pointing this out) **

image
Source: How to use math.noise? - Scripting Helpers

image
Source: math


I had thought he wanted the trees to populate randomly, but as you stated correctly, if he wanted it to be the same every time he could use math.ranomseed()

My bad, i thought it was a value between -1 and 1. Thanks for letting me know :smiley:

math.noise actually returns values from -1 to 1.

It just depends on the type of parameter you pass (int or float) to determine what range you will “see”

Correct, sorry I should have double checked; I have updated my reply :slight_smile:

To be quite honest, for the best outcome perlin noise for trees isnt your best choice. I recommend just generating a random number and checking if its == 10 or something. From my expierience that works best, but asking someone like @Elttob would probably help too.

It worked better but there are a lot of trees.

You can control how many trees there are by changing the threshold; lower means more dense. For example, you could set it to 0.95 for sparse trees, or 0.75 for very dense. I added a comment in my code when I posted it to explain this somewhat:

Thank you it worked. You helped me a lot.

Thank you too (30 character limit)