diff --git a/scripts/world/terrain.gd b/scripts/world/terrain.gd index 1d5289c..ab68b48 100644 --- a/scripts/world/terrain.gd +++ b/scripts/world/terrain.gd @@ -29,8 +29,10 @@ func _build() -> void: var step := float(size) / float(resolution) var half := size * 0.5 + var uv_scale := 1.0 / float(size) - # Build a grid of quads, two triangles each. + # Build a grid of quads, two triangles each. Each vertex carries a planar UV + # (world-XZ mapped to 0..1) so the surface is ready for texturing later. for z in range(resolution): for x in range(resolution): var x0 := x * step - half @@ -43,11 +45,13 @@ func _build() -> void: var p01 := Vector3(x0, _height(noise, x0, z1), z1) var p11 := Vector3(x1, _height(noise, x1, z1), z1) - _add_tri(st, p00, p01, p11) - _add_tri(st, p00, p11, p10) + _add_tri(st, p00, p01, p11, half, uv_scale) + _add_tri(st, p00, p11, p10, half, uv_scale) + # Normals give the lighting its shape. Tangents are only needed for normal + # maps, which this low-poly material doesn't use — so we skip them (and avoid + # the "UVs required to generate tangents" error). st.generate_normals() - st.generate_tangents() var mesh := st.commit() var mi := MeshInstance3D.new() @@ -71,7 +75,10 @@ func _build() -> void: func _height(noise: FastNoiseLite, x: float, z: float) -> float: return noise.get_noise_2d(x, z) * height_scale -func _add_tri(st: SurfaceTool, a: Vector3, b: Vector3, c: Vector3) -> void: +func _add_tri(st: SurfaceTool, a: Vector3, b: Vector3, c: Vector3, half: float, uv_scale: float) -> void: + st.set_uv(Vector2((a.x + half) * uv_scale, (a.z + half) * uv_scale)) st.add_vertex(a) + st.set_uv(Vector2((b.x + half) * uv_scale, (b.z + half) * uv_scale)) st.add_vertex(b) + st.set_uv(Vector2((c.x + half) * uv_scale, (c.z + half) * uv_scale)) st.add_vertex(c)