Change Material texture with code

Godot Version

4

Question

Hello,

I would like to know if it’s possible to change the texture of a material using code. I am downloading images from our website and want to set them as textures for an Instance3D. Is this possible?

I already have a function that downloads the images as ImageTexture, but whenever I try to assign them as an override material, I end up with a magenta plane.

func set_texture(texture: ImageTexture, target: String):
	var root = self.get_parent()
	var debugSprite = root.find_child("Sprite3D") as Sprite3D
	debugSprite.texture = texture
	
	var target_node = root.find_child(target)
	if target_node != null:
		var image_plane = target_node.find_child("Plane") as MeshInstance3D
		if image_plane != null:
			print("Ziel gefunden! Textur wird angewendet.")		
			var material = StandardMaterial3D.new()
			material.albedo_texture = texture			
			image_plane.set_surface_override_material(0, material)
		else:
			print("Keine Plane unter dem Zielknoten gefunden.")
	else:
		print("Zielknoten nicht gefunden.")

mm try this:

image_plane.material_override = material

i allready tryed this before but the texture is magenta all the time. When i load the ImageTexture into an sprite its works fine.

How do you download the images?

If loading an image from resource it will be CompressedTexture2D instead of ImageTexture. The code below works for me:

var material = StandardMaterial3D.new()
var texture = load("res://assets/sprites/project_icon.png") as CompressedTexture2D
material.albedo_texture = texture
$Plane.set_surface_override_material(0, material)
1 Like

i download it from our webspace. Its not possible to have it in the project itself. Its for an online gallery. This is how i load the image

func load_image_from_url(image_url: String) -> ImageTexture:
	var error = http_request.request(image_url)
	if error != OK:
		print("Fehler bei der Anfrage: ", error)
		return null
	
	var result = await http_request.request_completed
	var response_code = result[1]
	var body = result[3]
	
	if response_code == 200:
		var image = Image.new()
		var load_error = image.load_jpg_from_buffer(body)
		if load_error == OK:
			print("Image loaded. Width: ", image.get_width(), " Height: ", image.get_height())
			var texture = ImageTexture.new()
			texture.create_from_image(image)
			print("Texture loaded")
			return texture 
		else:
			print("Error while loading the image: ", load_error)
			return null
	else:
		print("HTTP Request error: ", response_code)
		return null

Anyway, your code works fine for me. Any extra infomation like scene structure, image url or Godot version?

image

extends Node

func _ready() -> void:
	var image_url = "https://forum.godotengine.org/user_avatar/forum.godotengine.org/dctewi/288/30284_2.png"
	var image = await load_image_from_url(image_url)
	set_texture(image, "Node3D")

func load_image_from_url(image_url: String) -> ImageTexture:
	var error = $HTTPRequest.request(image_url)
	if error != OK:
		print("Fehler bei der Anfrage: ", error)
		return null
	
	var result = await $HTTPRequest.request_completed
	var response_code = result[1]
	var body = result[3]
	
	if response_code == 200:
		var image = Image.new()
		var load_error = image.load_png_from_buffer(body)
		if load_error == OK:
			print("Image loaded. Width: ", image.get_width(), " Height: ", image.get_height())
			var texture = ImageTexture.create_from_image(image)
			print("Texture loaded")
			return texture 
		else:
			print("Error while loading the image: ", load_error)
			return null
	else:
		print("HTTP Request error: ", response_code)
		return null

func set_texture(texture: ImageTexture, target: String):
	var root = self.get_parent()
	var debugSprite = root.find_child("Sprite3D") as Sprite3D
	debugSprite.texture = texture
	
	var target_node = root.find_child(target)
	if target_node != null:
		var image_plane = target_node.find_child("Plane") as MeshInstance3D
		if image_plane != null:
			print("Ziel gefunden! Textur wird angewendet.")
			var material = StandardMaterial3D.new()
			material.albedo_texture = texture
			image_plane.set_surface_override_material(0, material)
		else:
			print("Keine Plane unter dem Zielknoten gefunden.")
	else:
		print("Zielknoten nicht gefunden.")

this is how it looks for me.

this is my scene structure

and this is the Image_ node where i want to set the texture

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.