Confused about texture UVS

Godot Version

v4.6 stable

Question

Hello! I am confused about texture UVs as I got them all correctly mapped using a texture atlas, just the textures are rotated differently on all sides, I do not know how to fix this. I was following this tutorial: https://www.youtube.com/watch?v=6kfUlmv6bvc&list=PLqF5LscxmBZWBPnlnPg_OSr2xd_WkSGuG&index=1

(texture atlas in question attached for clarity)

textureatlas

@tool
extends MeshInstance3D

@export var block_size : float = 1.0
@export var chunk_width : int = 4
@export var chunk_height : int = 16
@export var chunk_depth : int = 4
@export_category("Texture Settings")
@export var atlas_texture : Texture2D
@export var atlas_columns : int = 3
@export var atlas_rows : int = 1
var block_mesh : ArrayMesh
var voxels = []
var rng = RandomNumberGenerator.new()

const FACE_TOP : = 0
const FACE_BOTTOM : = 1
const FACE_SIDE : = 2

const BLOCKS : = {
	0 : {"name" : "Air", "solid" : false, "tileData" : {FACE_TOP : Vector2i(0,0), FACE_BOTTOM : Vector2i(0,0), FACE_SIDE : Vector2i(0,0)}},
	1 : {"name" : "Grass", "solid" : true, "tileData" : {FACE_TOP : Vector2i(2,0), FACE_BOTTOM : Vector2i(0,0), FACE_SIDE : Vector2i(1,0)}},
	2 : {"name" : "Dirt", "solid" : true, "tileData" : {FACE_TOP : Vector2i(0,0), FACE_BOTTOM : Vector2i(0,0), FACE_SIDE : Vector2i(0,0)}},
	3 : {"name" : "Stone", "solid" : true, "tileData" : {FACE_TOP : Vector2i(0,1), FACE_BOTTOM : Vector2i(0,1), FACE_SIDE : Vector2i(0,1)}},
	4 : {"name" : "Test Block", "solid" : true, "tileData" : {FACE_TOP : Vector2i(1,1), FACE_BOTTOM : Vector2i(1,1), FACE_SIDE : Vector2i(1,1)}}
}

func _ready() -> void:
	var rand_gen = RandomNumberGenerator.new()
	voxels = generate_voxels()
	generate_mesh(voxels)
	var mat : = StandardMaterial3D.new()
	mat.albedo_texture = atlas_texture
	mat.texture_filter = BaseMaterial3D.TEXTURE_FILTER_NEAREST
	material_override = mat

func generate_mesh(voxels):
	var faces = []
	for x in range(voxels.size()):
		for y in range(voxels[x].size()):
			for z in range(voxels[x][y].size()):
				var block_id : int = voxels[x][y][z]
				if block_id == 0:
					continue
				if voxels[x][y][z] != 0:
					var position = Vector3(x,y,z) * block_size
					if x == 0 or voxels[x - 1][y][z] == 0:
						var t := block_tile_for_face(block_id, Vector3.LEFT)
						faces.append(create_face(Vector3.LEFT, position, get_tile_uvs(t.x, t.y)))
					if x == voxels.size() - 1 or voxels[x + 1][y][z] == 0:
						var t := block_tile_for_face(block_id, Vector3.RIGHT)
						faces.append(create_face(Vector3.RIGHT, position, get_tile_uvs(t.x, t.y)))
					if y == 0 or voxels[x][y - 1][z] == 0:
						var t := block_tile_for_face(block_id, Vector3.DOWN)
						faces.append(create_face(Vector3.DOWN, position, get_tile_uvs(t.x, t.y)))
					if y == voxels[x].size() - 1 or voxels[x][y + 1][z] == 0:
						var t := block_tile_for_face(block_id, Vector3.UP)
						faces.append(create_face(Vector3.UP, position, get_tile_uvs(t.x, t.y)))
					if z == 0 or voxels[x][y][z - 1] == 0:
						var t := block_tile_for_face(block_id, Vector3.FORWARD)
						faces.append(create_face(Vector3.FORWARD, position, get_tile_uvs(t.x, t.y)))
					if z == voxels[x][y].size() - 1 or voxels[x][y][z + 1] == 0:
						var t := block_tile_for_face(block_id, Vector3.BACK)
						faces.append(create_face(Vector3.BACK, position, get_tile_uvs(t.x, t.y)))
	var vertices = []
	var normals = []
	var uvs = []
	for face in faces:
		vertices += face["vertices"]
		normals += face["normals"]
		uvs += face["uvs"]
	var vertex_array = PackedVector3Array(vertices)
	var normal_array = PackedVector3Array(normals)
	var uv_array = PackedVector2Array(uvs)
	var arrays = []
	arrays.resize(Mesh.ARRAY_MAX)
	arrays[Mesh.ARRAY_VERTEX] = vertex_array
	arrays[Mesh.ARRAY_NORMAL] = normal_array
	arrays[Mesh.ARRAY_TEX_UV] = uv_array
	block_mesh = ArrayMesh.new()
	block_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
	self.mesh = block_mesh

func generate_voxels() -> Array:
	rng.randomize()
	var array = []
	array.resize(chunk_width)
	for x in chunk_width:
		array[x] = []
		array[x].resize(chunk_height)
		for y in chunk_height:
			array[x][y] = []
			array[x][y].resize(chunk_depth)
	for x in chunk_width:
		for y in chunk_height:
			for z in chunk_depth:
				array[x][y][z] = rng.randi_range(0,1)
				
	return array

func create_face(direction : Vector3, position: Vector3, uv_coords : Array) -> Dictionary:
	var vertices = []
	var normals = []
	var uvs = []
	normals.resize(4)
	match direction:
		Vector3.UP:
			vertices = [
				position + Vector3(-0.5, 0.5, -0.5) * block_size,
				position + Vector3(0.5, 0.5, -0.5) * block_size,
				position + Vector3(0.5, 0.5, 0.5) * block_size,
				position + Vector3(-0.5, 0.5, 0.5) * block_size
			]
			normals.fill(Vector3.UP)
			uvs = uv_coords
		Vector3.DOWN:
			vertices = [
				position + Vector3(-0.5, -0.5, 0.5) * block_size,
				position + Vector3(0.5, -0.5, 0.5) * block_size,
				position + Vector3(0.5, -0.5, -0.5) * block_size,
				position + Vector3(-0.5, -0.5, -0.5) * block_size
			]
			normals.fill(Vector3.DOWN)
			uvs = uv_coords
		Vector3.LEFT:
			vertices = [
				position + Vector3(-0.5, -0.5, -0.5) * block_size,
				position + Vector3(-0.5, 0.5, -0.5) * block_size,
				position + Vector3(-0.5, 0.5, 0.5) * block_size,
				position + Vector3(-0.5, -0.5, 0.5) * block_size
			]
			normals.fill(Vector3.LEFT)
			uvs = uv_coords
		Vector3.RIGHT:
			vertices = [
				position + Vector3(0.5, -0.5, 0.5) * block_size,
				position + Vector3(0.5, 0.5, 0.5) * block_size,
				position + Vector3(0.5, 0.5, -0.5) * block_size,
				position + Vector3(0.5, -0.5, -0.5) * block_size
			]
			normals.fill(Vector3.RIGHT)
			uvs = uv_coords
		Vector3.FORWARD:
			vertices = [
				position + Vector3(-0.5, -0.5, -0.5) * block_size,
				position + Vector3(0.5, -0.5, -0.5) * block_size,
				position + Vector3(0.5, 0.5, -0.5) * block_size,
				position + Vector3(-0.5, 0.5, -0.5) * block_size
			]
			normals.fill(Vector3.FORWARD)
			uvs = uv_coords
		Vector3.BACK:
			vertices = [
				position + Vector3(-0.5, 0.5, 0.5) * block_size,
				position + Vector3(0.5, 0.5, 0.5) * block_size,
				position + Vector3(0.5, -0.5, 0.5) * block_size,
				position + Vector3(-0.5, -0.5, 0.5) * block_size
			]
			normals.fill(Vector3.BACK)
			uvs = uv_coords
	return{
		"vertices" : [
			vertices[0], vertices[1], vertices[2],
			vertices[0], vertices[2], vertices[3]
		],
		"normals" : [
			normals[0], normals[1], normals[2],
			normals[0], normals[2], normals[3]
		],
		"uvs" : [
			uvs[0], uvs[1], uvs[2],
			uvs[0], uvs[2], uvs[3]
		]
	}

func block_tile_for_face(block_id: int, face_dir: Vector3) -> Vector2i:
	var block = BLOCKS.get(block_id, BLOCKS[0])
	var tiles = block["tileData"]
	
	if face_dir == Vector3.UP:
		return tiles[FACE_TOP]
	elif face_dir == Vector3.DOWN:
		return tiles[FACE_BOTTOM]
	elif face_dir == Vector3.LEFT:
		return tiles[FACE_SIDE]
	elif face_dir == Vector3.RIGHT:
		return tiles[FACE_SIDE]
	elif face_dir == Vector3.FORWARD:
		return tiles[FACE_SIDE]
	elif face_dir == Vector3.BACK:
		return tiles[FACE_SIDE]
	else:
		return tiles

func get_tile_uvs(tile_x : int, tile_y : int) -> Array:
	var tex_w = float(atlas_texture.get_width())
	var tex_h = float(atlas_texture.get_height())
	var tile_w_pixel = tex_w / float(atlas_columns)
	var tile_h_pixel = tex_h / float(atlas_rows)
	var u0 = (tile_x * tile_w_pixel) / tex_w
	var v0 = (tile_y * tile_h_pixel) / tex_h
	var u1 = ((tile_x + 1) * tile_w_pixel) / tex_w
	var v1 = ((tile_y + 1) * tile_h_pixel) / tex_h
	return [
		Vector2(u0, v1),
		Vector2(u1, v1),
		Vector2(u1, v0),
		Vector2(u0, v0)
	]