2D - Problem with re-using textures for multiple polygons

Godot Version

4.2

Question

I’m trying to create irregular shaped tiles using polygons, and I want to use the same texture for each tile. I have the minimum code below that creates a number of polygons in a row.

The texture for the first polygon is displayed properly, but for the remaining polygon, only a plain green texture is shown. I suspect the issue might be something to do with either UVs (which I’ve left empty), or how I’ve imported the texture resource.

Does anyone know what I’m doing wrong? I’ve linked below the texture I’m using, plus the test result.

PolygonTestResult

CODE:

extends Node2D

# VARS

# the texture for each polygon
@onready var grass_texture : Texture2D = preload("res://grass_texture.png")

# the shape of the polygon - 64 x 64 square
@onready var polygon_corners : PackedVector2Array = [
	Vector2(0, 0),
	Vector2(64, 0),
	Vector2(64, 64),
	Vector2(0, 64),
]

# the number of polygons in a row
@onready var number_of_polygons : int = 3

# the spacing between the top-left corner of each polygon
@onready var polygon_spacing : Vector2 = Vector2(128, 0)


# FUNCS
func _ready():
	
	# for each polygon
	for polygon_number in number_of_polygons:
		
		# create a variable to hold the updated coordinates for each corner
		var corner_coordinates : PackedVector2Array
		
		# for each corner, take the original position, and create world coordinates based on which polygon it is
		for corner in polygon_corners:
			var corner_coordinate : Vector2 = corner + (polygon_spacing * polygon_number)
			corner_coordinates.append(corner_coordinate) # add coordinates to the holding variable
		
		# now we have the coordinates, create a polygon
		var new_polygon = Polygon2D.new()
		
		# add the coordinates data, the texture, and add it to the tree
		new_polygon.polygon = corner_coordinates
		new_polygon.texture = grass_texture
		add_child(new_polygon)

I’ve now resolved this but not quite in the way I’d expected. It comes down to a couple of things I wasn’t aware of (and aren’t documented very well).

I was trying to use Polygon2D essentially as just an irregular-shaped version of Sprite2D, but they don’t work in the same way at all. Instead of them being ‘frames’ for a single texture, in the way that Sprite2Ds are, they seem to assume that you’ll be using a tiled pattern texture instead. So, if you want to use them as an irregular-shaped Sprite2D, you need to keep in mind:

  1. You’ll need to make use of the UVs - but they don’t work like shader UVs. They work based on the texture pixels. So instead of a range of 0 to 1, they would be 0 to 256 for example (for a 256 x 256 px texture).
  2. You’ll also need to use the offset. Regardless of where you place the polygon or how you set the UV, the top left of your image (prior to the offset) will always be at (0, 0). If you place a polygon without an offset anywhere else on the screen, you’ll just get a stretched/repeated colour of the last row/column of pixels, as I have in the image above. In my image, the other boxes are green because the last column of the texture is green. And just to confuse things, the offset seems to swap positive and negative vectors, so if you want a polygoin with your image at Vector2(256, 0) in screen space, your offset will need to be (-256, 0). No idea why this is but it works.

Hope that helps someone else.