Terrain GapFIll

Hello,
I recently imported a heightmap into roblox for a large-scale game I plan to build. Unfortunately, my heightmap importer doesn’t set the thickness of the terrain very high. This leads to problems in the future. Maybe some of you guys could help.

Here is my terrain when I import it. Nothing new, just a bunch of wedges with meshes that make them infinitely thin.

Now here, I’ve converted my triangles to terrain. It looks fine, right? Well…

The terrain is littered with these square holes, and it drives me crazy. This is due to the terrain being too thin for accurate slopes. If there were a way to make the terrain thicker, I wouldn’t have to worry about this.

The best way to fix it, in my opinion, is to perform a function like Stravant’s GapFill on the terrain. I want to dig tunnels anyways, so this would probably be my best option. The only thing is I’d rather not have to click every wedge, kill my computer’s framerate in the process, and waste hours of my time, so if anyone knows how I can go about filling the gap between the (uneven) bottom of my terrain, and a baseplate part I place underneath, it would be much appreciated! :smiley: Thanks,
-big

Nah just run the smooth brush over it. Cleans it up real fast

I can’t use the smooth brush; 1. terrain’s too big. 2. it’s too small, the brush eats away too many cells and it makes holes in the terrain.

Do you mean your terrain is entirely hollow? That’s the vibe I’m getting.

Think about it like a blanket that’s floating in the air; it doesn’t get thicker or thinner, it just changes it’s height.

therefore its hollow

1 Like

So yes, entirely hollow. That’s a bit of a pickle lmao.
I’ve never worked with terrain from the Lua end so this might not be possible or easy, but theoretically, after you’ve converted to terrain, can’t you have a script grab every voxel from the affected region into the 3d table format, and modify the table to fill voxels down from each full voxel in the table down to a particular height? Since this is a heightmap you don’t need to worry about caves and overhangs, and since it’s a thin layer of terrain, there won’t be that many full voxels to project downwards. Afterwards you can simply regenerate the terrain from the modified table.

Hopefully that makes sense.

Ah, unfortunately I’m not up on terrain API’s, so I don’t quite know what you mean. Do you think cloning the parts and moving them down by a stud at a time would work? The bottom wouldn’t be flat, but it might work.

What he could do is get the normal of the terrain voxel, get the lookVector, go backwards of the lookVector and draw more terrain there so he can smooth it, or he can just make the terrain cells larger in size

He wants terrain to be solid so he can carve tunnels into it. The easiest way to do that, that I can think of is to just draw full voxels all the way down from each existing voxel to create a brick of terrain like how the terrain generation tools normally produce. Needing to smooth the terrain over a bit afterwards is almost 100% going to be necessary though.

Cloning the parts many times downwards might work, but is certainly not going to be fast.

Oh, thought he just wanted to fix the holes. (Otherwise, if he wants to fix the height issues he can just set the size to the maximum height and set the y position of the cframe to h+(s.y/2))

Here’s something I slapped together that works on a small scale. No idea if it will work for the size of what you need, but you can try it. Might want to set batch size a bit higher or it will take forever. But also too high and Studio might start freaking out thinking you’ve crashed.

You can run this from the command bar, but there will be NO UNDO unless you did something before running the command to undo.

-- BACK UP YOUR SAVE BEFORE RUNNING THIS

local Terrain = workspace.Terrain
wait(2)

-- Parameters
local fillMaterial = Enum.Material.Ground
local batchSize = 500 -- Voxels to do before printing progress. Too high = freezing
local startCorner = Vector3.new(-141, 14, -150)
local endCorner = Vector3.new(147, -26, 155)

-- No touchy
local resolution = 4
local region = Region3.new(
    Vector3.new(
        math.min(startCorner.X, endCorner.X),
        math.min(startCorner.Y, endCorner.Y),
        math.min(startCorner.Z, endCorner.Z)
    ),
    Vector3.new(
        math.max(startCorner.X, endCorner.X),
        math.max(startCorner.Y, endCorner.Y),
        math.max(startCorner.Z, endCorner.Z)
    )
)
region = region:ExpandToGrid(resolution)

local material, occupancy = game.Workspace.Terrain:ReadVoxels(region, resolution)
local size = material.Size
local currBatch = 0
local elapsedBatches = 0
local totalBatches = size.X*size.Y*size.Z/batchSize

for x = 1, size.X do
	for y = 1, size.Y do
		for z = 1, size.Z do
			currBatch = currBatch + 1
			
			if occupancy[x][y][z] > 0 then
				for yi = y-1, 1, -1 do
					occupancy[x][yi][z] = 1
					material[x][yi][z] = fillMaterial
				end
			end
			
			if (currBatch >= batchSize) then
				currBatch = 0
				elapsedBatches = elapsedBatches + 1
				print("%" .. elapsedBatches / totalBatches * 100)
				wait()
			end
		end
	end
end

print("Clearing")
Terrain:Clear()
print("Writing")
Terrain:WriteVoxels(region, 4, material, occupancy)

What it does in a nutshell:

6 Likes

It looks like that’s what I’m looking for. I’ll give it a try and get back to you in a couple minutes.

No idea if this problem is still a issue for you, but it seems that you are having a problem with the holes in your terrain, if you want to easily fix it if you don’t mind the SMALLEST deviation to your terrain is if you use the grow tool, just set the strength halfway and then glide it over the area, it should fill in the holes without much change to the general shape of the terrain. I hope this helps.