Squashing 4D Noise for procedural base Terrain Generation

I am currently following a tutorial for terrain generation for Minecraft from Henrik Kniberg (Minecraft terrain generation in a nutshell - YouTube) and while doing this I am trying to implement these concepts into Roblox for terrain generation. Right now I am struggling with how to make, what he calls a “squashing factor” (from 18:12 to 19:50 in the video) for the base/general terrain generation.

I am using an OpenSimplex Module from Feedekaiser: OpenSimplex Noise in Lua!
(i am using this module because it has support for 4D (which is required for the purposes of this mechanic, for seeds, which is actually pointless with this module because you have to “seed it” in the beginning and so you should just use the 3D functions for it) and it’s SIMPLEX, not Perlin so its better)

The problem now is that I here I am supposed to put some code to show my progress and more specific problem, but I can’t, because I have no idea how to approach the problem. (well ofc I did had ideas, but they didn’t show the desired results, so i just scrapped them)

But the general understanding of what should happen is that with the 4D noise you create these “cheese holes patterns” by getting the value for each X, Y and Z axis from the noise and check if the value is positive or negative (if negative or 0 = air, if > 0 = fill).

Then the next step is to use this squashing factor in order to… squash the terrain, by using a center point which keeps the terrain the same there.

One of my ideas was to make the terrain more sparse as the Y/height value increased and more dense as it was getting more negative. This might be the right way to think about it and do it, but I just couldn’t figure it out in code. I did try certainly, I tried by either changing the frequency/lacunarity and amplitude/persistence, or checking if the Y/height value was over/under a certain threshold and do changes accordingly or mixed them both, without success.

He does mention that these values for the squashing are controlled by spline points from the previous chapter of the video. Which spline points, control the continentalness, erosion and peaks and valleys, so maybe when I combine them all… it, may work?

1 Like

They are choosing density based on height, the air <= 0 : fill > 0 is instead replaced with the height value.

local noise_value: number = math.noise(x, y, z)
local fill: boolean = noise_value < y

squashing would be to multiply or divide the y comparison. You are right to want to add many more parameters based on what biome you want to achieve, though this is only the first step for base terrain as they point out in the video

local noise_value: number = math.noise(x, y, z)

local squashing_factor: number = 0.4
 -- over twice as likely to be filled, a low squashing factor
local fill: boolean = noise_value < (y * squashing_factor)
1 Like

Ok, thank you for the reply. I did try to implement your way, but it didn’t give the results I wanted. But I did continue trying and ended up doing exactly what I wanted. Here’s the rough code:

for x=fromX, toX do
	for z=fromZ, toZ do
		for y=fromY, toY do
			local percentageForCurrentHeight = y/(maxHeight/2) -- from -1 to 1
			local percentageForCurrentHeightFrom0To1 = (1 + percentageForCurrentHeight)/2 -- from 0 to 1
			local inversedPercentageForCurrentHeightFrom0To1 = math.abs(percentageForCurrentHeightFrom0To1 - 1) -- "inversed" percentageForCurrentHeightFrom0To1
			
			local noise = noise(x, y*inversedPercentageForCurrentHeightFrom0To1*squashingFactor, z)
			
			if noise*inversedPercentageForCurrentHeightFrom0To1*squashingFactor > y then
				generateVoxel(Vector3.new(x, y, z))
			end
		end
	end
end

It might have some problems here and there, but generally it does what it’s supposed to and here it is:
The idea is that we don’t just want to scale the frequency or amplitude linearly depending on the height/Y, but we need to decrease/increase density for +Y/-Y respectively exponentially, so we can actually squash the terrain around the center point. This happens as the height/Y gets further away from the center point, the rate at which the density will grows (+Y/-Y respectively) gets bigger and bigger so less/more density (+Y/-Y respectively) with each higher point (exponential). And like that we have the terrain @ the center point unchanged, because, you could say it’s infinitely close to the center point. And of course you have the constant SquashingFactor which determines the overall effect of the mechanic.

I’ve made a rough sketch of how you could imagine it:

It’s something like a cubic function between 0 and 1 and the input is height/Y.

And in the end you get the results:


Although I don’t know why some sort of error in the calculations exists:


It’s some sort of problem, like banding or something, with the Module I use to get the 4D Noise. I have tried 3 different Modules and all of them have the same issue with the 4th dimension. It’s either that or I just don’t use them correct or something, I don’t know.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.