Creating Decals on runtime freezes the game for a few seconds

Godot Version

4.3

Question

Hi, I’m having issues painting decals in the world as sometimes freezes . I’m preloading the textures and assigning them on runtime creating instances, is this a normal behaviour?

It also happens if I create a scene with the decal node and the textures preassigned.

This is my code, I’m creating raycast from code, I can confirm that the creation of these raycasts does not lower my fps or anything else. I am 100% sure it is the decals.

Using the raycast result I do the following, the scene I use is just a decal node but with a script to adjust the decal to the surface, nothing fancy

if not result.is_empty():
	var blood_splatter = Preloader.BloodSplatterScene.instantiate() as SmartDecal
	var blood_splatter_texture: Dictionary = Preloader.BloodSplatterTextures.pick_random()
		
	blood_splatter.min_size = blood_splatter_min_size
	blood_splatter.max_size = blood_splatter_max_size
	blood_splatter.spin_randomization = true
	blood_splatter.fade_after = 0
	blood_splatter.texture_albedo = blood_splatter_texture.albedo
	blood_splatter.texture_normal = blood_splatter_texture.normal if blood_splatter_texture.has("normal") else null
	blood_splatter.texture_orm = blood_splatter_texture.orm if blood_splatter_texture.has("orm") else null
		
	result["collider"].add_child(blood_splatter)
		
	blood_splatter.position = result["position"]
	blood_splatter.adjust_to_normal(result["normal"])

and this is the Preloader in case it is needed:

class_name Preloader

const BloodSplatterScene: PackedScene = preload("res://scenes/world/weapons/bullets/blood/splatters/blood_splatter.tscn")

const BloodSplatterTextures: Array[Dictionary] =  [
	{"albedo": preload("res://assets/decals/blood/Blood_1.png"), "normal": preload("res://assets/decals/blood/Blood_1_Normal.png")},
	{"albedo": preload("res://assets/decals/blood/Blood_2.png"), "normal": preload("res://assets/decals/blood/Blood_2_Normal.png")},
	{"albedo": preload("res://assets/decals/blood/Blood_5.png"), "normal": preload("res://assets/decals/blood/Blood_5_Normal.png")},
	{"albedo": preload("res://assets/decals/blood/Blood_6.png"), "normal": preload("res://assets/decals/blood/Blood_6_Normal.png")},
	{"albedo": preload("res://assets/decals/blood/Blood_7.png"), "normal": preload("res://assets/decals/blood/Blood_7_Normal.png")},
	{"albedo": preload("res://assets/decals/blood/Blood_8.png"), "normal": preload("res://assets/decals/blood/Blood_8_Normal.png")},
	{"albedo": preload("res://assets/decals/blood/Blood_11.png"), "normal": preload("res://assets/decals/blood/Blood_11_Normal.png")},
	{"albedo": preload("res://assets/decals/blood/TX_Decal_Blood_Floor_AL.png"), "normal": preload("res://assets/decals/blood/TX_Decal_Blood_Floor_NR.png"), "orm": preload("res://assets/decals/blood/TX_Decal_Blood_Floor_ORM.png")}
]

I can share a video to better visualize what is happening, I tried to record it with Godot’s movie maker but instead of showing the slowdown it makes some jumps in the video.

After a while I found that I had enabled the Distance fade parameter on the Decal but Isn’t it supposed to improve performance and it causes me just the opposite?

Not necessarily.
One of the reasons for the distance fade is to smoothly make the decals disappear. It involves calculating when it should happen and changing its transparency over time.

This can be even more costly than simply letting them exist depending on the number of them.
Or making a simple script that just erases them by distance.

You can try to reduce the distance_fade to make the transparency fade happen over less distance which might improve performance a little.