Bleeding textures on cube

Godot Version

4.3 stable

Question

Hello, just starting out and probably making stupid mistakes.

Been trying to fix this for a few days, but I think it’s beyond me.

I’m trying to construct a 3D cube with different textures for each face. The top and bottom will have texture top, and the 4 side faces of the cube will have a “side” texture. For some reasoon, the top texture is coming and clipping into the side texture:


What the top looks like:
stone_top
And side texture:
stone_side
Here’s what it looks like with ALBEDO = vec3(UV, 0.0);:

Here’s my shader:

shader_type spatial;

uniform sampler2D top_texture;
uniform sampler2D side_texture;
uniform float texture_scale = 1.0;

varying vec3 face_normal;
varying vec2 custom_uv;

void vertex() {
	face_normal = NORMAL;
	custom_uv = UV * texture_scale;
}

void fragment() {
	vec3 normal_dir = normalize(face_normal);

	if (normal_dir.y > 0.5) {
		ALBEDO = texture(top_texture, custom_uv).rgb;
	} else { 
		ALBEDO = texture(side_texture, custom_uv).rgb;
	}
	//ALBEDO = vec3(UV, 0.0);
}

And I’m using it like:

func add_face(pos, normal, block_type, surface_tool) -> int:
	var half_size = BLOCK_SIZE * 0.5
	var vertices = []
	var uv_coords = []

	# Select correct textures
	var top_texture = block_types[block_type]["textures"]["top"][0]
	var side_texture = block_types[block_type]["textures"]["side"][0]

	if normal == Vector3(0, 1, 0):  # Top Face
		vertices = [
			pos + Vector3(-half_size, half_size, -half_size),
			pos + Vector3(half_size, half_size, -half_size),
			pos + Vector3(half_size, half_size, half_size),
			pos + Vector3(-half_size, half_size, half_size)
		]
		uv_coords = [Vector2(0, 1), Vector2(1, 1), Vector2(1, 0), Vector2(0, 0)]

	elif normal == Vector3(0, -1, 0):  # Bottom Face
		vertices = [
			pos + Vector3(-half_size, -half_size, -half_size),
			pos + Vector3(-half_size, -half_size, half_size),
			pos + Vector3(half_size, -half_size, half_size),
			pos + Vector3(half_size, -half_size, -half_size)
		]
		uv_coords = [Vector2(1, 1), Vector2(1, 0), Vector2(0, 0), Vector2(0, 1)]

	else:  # Side Faces
		if normal == Vector3(1, 0, 0):  # Right Face
			vertices = [
				pos + Vector3(half_size, -half_size, -half_size),
				pos + Vector3(half_size, -half_size, half_size),
				pos + Vector3(half_size, half_size, half_size),
				pos + Vector3(half_size, half_size, -half_size)
			]
		elif normal == Vector3(-1, 0, 0):  # Left Face
			# Snip for berevity
		elif normal == Vector3(0, 0, 1):  # Front Face
			# Snip for berevity
		elif normal == Vector3(0, 0, -1):  # Back Face
			# Snip for berevity

		uv_coords = [Vector2(0, 1), Vector2(1, 1), Vector2(1, 0), Vector2(0, 0)]

	var indices = [0, 1, 2, 0, 2, 3]

	var material = ShaderMaterial.new()
	material.shader = load("res://shaders/block_shader.gdshader")
	material.set_shader_parameter("top_texture", top_texture)
	material.set_shader_parameter("side_texture", side_texture)

	surface_tool.set_material(material)

	for i in indices:
		surface_tool.set_normal(normal)
		surface_tool.set_uv(uv_coords[i % 4])
		surface_tool.add_vertex(vertices[i])

	return 6

The way I’d do it is to open the cube in blender and correct the texture by hand in blender (you can do texture paint)