Need help with shaping procedural island generation

Godot Version

4.2.1.stable

Question

Hey everyone,

I’m currently working on a procedural island generation project in Godot Engine, and I’ve hit a bit of a roadblock. While I’ve successfully generated a map using Perlin noise based on a seed, I’m struggling with shaping it into a recognizable island form.

I came across a tutorial by Dani on YouTube where he implements a survival game Dani’s survival game, and he adds a Falloff to shape the generated terrain into islands. Additionally, I found some techniques like Square Bump and Euclidean mentioned in this resource here that seem promising for island shaping.

However, I’m not entirely sure how to integrate these techniques into my GDScript code. Could someone please provide some guidance or point me in the right direction? Any code snippets or explanations would be greatly appreciated.

Here’s a snippet of my current GDScript code for reference:

#https://www.youtube.com/watch?v=EEo5cuwjYhA&list=LL&index=2&ab_channel=Chevifier
@tool
extends MeshInstance3D

@export var xSize = 20
@export var zSize = 20
@export var terrain_height = 5
@export var noise_offset = 0.5
@export var update = false
@export var clear_vert_vis = false
var rng = RandomNumberGenerator.new()
var min_height = 0
var max_height = 1

func generate_random_terrain():
	var seed = rng.randi_range(0, 1000000)
	generate_terrain(seed)

func _ready():
	generate_random_terrain()

func generate_terrain(seed: int = 0):
	
	var a_mesh:ArrayMesh
	var surftool = SurfaceTool.new()
	var n = FastNoiseLite.new()
	n.set_seed(seed)
	
	n.noise_type = FastNoiseLite.TYPE_PERLIN
	n.frequency = 0.1
	surftool.begin(Mesh.PRIMITIVE_TRIANGLES)
	for z in range(zSize + 1):
		for x in range(xSize + 1):
			var y = n.get_noise_2d(x * noise_offset, z * noise_offset) * terrain_height
			if y < min_height and y != null:
				min_height = y
			if y > max_height and y != null:
				max_height = y
			
			var uv = Vector2()
			uv.x = inverse_lerp(0,xSize,x)
			uv.y = inverse_lerp(0,zSize,z)
			
			surftool.add_vertex(Vector3(x,y,z))
	
	var vert = 0
	for z in range(zSize):
		for x in range(xSize):
			surftool.add_index(vert + 0)
			surftool.add_index(vert + 1)
			surftool.add_index(vert + xSize + 1)
			surftool.add_index(vert + xSize + 1)
			surftool.add_index(vert + 1)
			surftool.add_index(vert + xSize + 2)
			vert += 1
		vert += 1
	surftool.generate_normals()
	a_mesh = surftool.commit()
	
	mesh = a_mesh
	update_shader()



func update_shader():
	var mat = get_active_material(0)
	mat.set_shader_parameter("min_height" , min_height)
	mat.set_shader_parameter("max_height" , max_height)


func draw_sphere(pos:Vector3):
	var ins = MeshInstance3D.new()
	add_child(ins)
	ins.position = pos
	var sphere = SphereMesh.new()
	sphere.radius = 0.1
	sphere.height = 0.2
	ins.mesh = sphere

func _process(delta):
	if update:
		generate_terrain()
		update = false
		
	if clear_vert_vis:
		for i in get_children():
			i.free()