Hello I’m trying to make a procedurally generated island. I would like to modify this code to make it look more natural. Now I don’t know if what I mean by natural is possible in Godot but what I’m trying to do is generate an island that looks like the one in Fortnite. I heard I needed some things called Rendering, Physics Server and Threading to make it look more natural but I’m unsure what those mean for procedural generation and if that’s actually what I’m looking for.
Here is my main code:
@tool
extends MeshInstance3D
@export var xSize = 20
@export var zSize = 20
@export var noise_offset = 0.5
@export var update = false
@export var clear_vert_vis = false
var min_height = 0
var max_height = 1
# Called when the node enters the scene tree for the first time.
func _ready():
generate_terrain()
func generate_terrain():
var a_mesh:ArrayMesh
var surfTool = SurfaceTool.new()
var n = FastNoiseLite.new()
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) * 5
if y < min_height and y != null:
min_height = y
if y > min_height and y != null:
max_height = y
var uv = Vector2()
uv.x = inverse_lerp(0,xSize,x)
uv.y = inverse_lerp(0,xSize,z)
surfTool.set_uv(uv)
surfTool.add_vertex(Vector3(x,y,z))
#draw_sphere(Vector3(x,y,z))
var vert = 0
for z in zSize:
for x in 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
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
if update:
generate_terrain()
update = false
if clear_vert_vis:
for i in get_children():
i.free()
Here is my shader code which you may or may not need:
shader_type spatial;
uniform sampler2D terrain_grass;
uniform sampler2D terrain_rock;
uniform float min_grass_height = -0.30;
uniform float max_rock_height = 1.6;
varying float vertex_y;
uniform vec2 uvscale = vec2(5);
void fragment() {
float vert_weight = vertex_y;
vec3 grass = texture(terrain_grass,UV*uvscale).rgb;
vec3 rock = texture(terrain_rock,UV*uvscale).rgb;
float weight = smoothstep(min_grass_height,max_rock_height, vert_weight);
vec3 final_color = mix(grass,rock,weight);
ALBEDO = final_color.rgb;
}
void vertex(){
vertex_y = VERTEX.y;
}