How to draw image based on values in array

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By blohod

I have an array of terrain types that are represented by numbers (0 = water, 1 = land, etc.)
I need each terrain type to show as a different coloured pixel.
I am currently using an ImageTexture but the create_from_image function is too slow as I want to update the image constantly. I have heard that maybe I should use a shader?

My current slow method:

extends Sprite

var terrain_image = Image.new()
var terrain_texture = ImageTexture.new()

func create_texture(width, height, terrain_array, depth_array):
	var color
	
	terrain_image.create(width, height, false, Image.FORMAT_RGBA8)
	terrain_image.lock()

	for y in range(height):
		for x in range(width):
			var current_material = terrain_array[y][x]
			var current_depth = depth_array[y][x]
			if  current_material == 0:
				color = Color.blue  # water
				color = color.darkened(abs(current_depth))
			elif current_material == 1:
				color = Color.yellow  # land
				color = color.darkened(current_depth)
			elif current_material == 2:
				color = Color.green
			else:
				color = Color.pink  # error
			terrain_image.set_pixel(x, y, color)

	terrain_image.unlock()
	terrain_texture.create_from_image(terrain_image, 0)


func draw_terrain(width, height, terrain_array, depth_array):
	create_texture(width, height, terrain_array, depth_array)
	self.texture = terrain_texture

I ended up using sprites for anything that needed quick updating

blohod | 2021-04-26 06:37

:bust_in_silhouette: Reply From: Jummit

Neither shaders nor ImageTextures are very efficient way of storing and updating a world, so in this case I’d just stick to using what Godot provides; the TileMap node. You can either create the TileSet manually or by code if you so whish.

Modifying a TileMap is still slow, though

exuin | 2021-04-18 17:44