MarchingCubesService - Generate Cool Caves In Seconds

MarchingCubesService

I created a module that can easily create caves in seconds. At the moment its basically just a tech demo that I may or may not improve on or add to at a later date.

Images and videos of what can be generated:



Install it here: MarchingCubesService - Roblox


How It Works

It samples points in 3d space and each point is given a unique perlin noise value. Then it marches over the points uses the noise values to create a cave like stucture.


How to use it

local MarchingCubesService = require(game:GetService("ReplicatedStorage").MarchingCubesService)

local marching = MarchingCubesService.new{
	LocalPosition=Vector2.new(0,0), -- the x and z coords of where the caves will be created
	LocalSize=Vector3.new(60,60,60), -- the size of the caves
	Gap=6 -- the distance in studs between the sample points, this also affects the scale
}
marching:marchAll()
9 Likes

It has quite a lot of room for scalability, but it is extremely buggy.

1 Like

could you elaborate by what you mean by it being extremely buggy? :wink:

The cave system is quite nice but maybe you should also add borders to the caves so a player can’t just jump into a new cave

1 Like

Interesting idea. I hadn’t thought of using MeshParts(?) for generating custom geometry programmatically on Roblox, but based on the videos the result is surprisingly good. How’s the performance considering marching cubes is typically done using a compute shader in game engines that support them?

1 Like

the performance isn’t actually as bad as you would expect.

heres a procedural terrain generation system that I made using the same marching cubes algorithm, albeit its 2d:

This is cool!

Is it possible to after it is generated, do some sorta of global smoothing of the surface, to reduce to eliminate the ‘triangle’ effects?

theres not much you can do to eliminate the triangle effects since the system is created from triangles. If you lower the Gap number then the triangles become smaller and therefore less noticeable.

mm, what about making the triangle also thicker? I am wondering about player bleed through if your head is close the to top of the terrain, like ur camera pans through it

making the triangle thicker leads to undesirable results


hmm thanks is kinda cool tho, what did you change to make it thicker

in the Draw3DTriangle Script on lines 30 and 33.

30 | Triangle.W1.Size = V3(0, Height, MathAbs(Dot(AB, Back)))
33 | Triangle.W2.Size = V3(0, Height, MathAbs(Dot(AC, Back)))

You change the X parameter (the “0”) in the V3 function to whatever thickness you desire.

ok, I am going to play around with them. Is the material changeable? I assume somewhere in the script

you can change the material of W1 and W2 inside of the Triangle Model of the Draw3DTriangle ModuleScript.

you have two links, which one is the latest or what is different?

could you elaborate by what you mean by two links?

and

two links and more words so it takes the reply I like roblox

the first link you mentioned is a demo game that uses the same marching cube alogorithm impemented in 2D. The second link you mentioned is the installation for the MarchingCubesService Module.

New Update :tada:

added more arguements for the MarchingCubesService.new function:

  • Material (the material of the caves)
  • Color (the color of the caves)
  • Smooth (disables interpolation resulting in the caves being less smooth)
  • NoiseFunc (the function used for calculating the noise of a given point. Must accept "x,y,z" as arguements.)

Here is an updated example of how to use the new arguements.

local MarchingCubesService = require(game:GetService("ReplicatedStorage").MarchingCubesService)

local function noise(x,y,z)
	return math.noise(x/40,y/40,z/40)
end

local marching = MarchingCubesService.new{
	LocalPosition=Vector2.new(0,0), -- the x and z coords of where the caves will be created
	LocalSize=Vector3.new(30,30,30), -- the size of the caves
	Gap=10, -- the distance in studs between the sample points, this also affects the scale
	Material=Enum.Material.Grass, -- the material of the caves
	Color=Color3.fromRGB(111, 126, 62), -- the color of the caves
	Smooth=true, -- disables interpolation resulting in the caves being less smooth
	NoiseFunc=noise -- the function used for calculating the noise of a given point. Must accept "x,y,z" as arguements.
}
marching:marchAll()

This looks awesome. Is there any chance that you could upload the source code on github?

1 Like