Freezes at assigning an exported ShaderMaterial in code the first time

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

I am seeing that this code gets freezes for almost 2 seconds on my mobile debug device:

@export var canvas_item: CanvasItem
@export var material: ShaderMaterial

[...]

# This line:
canvas_item.material = material

This is the Debugger > Profiler:

The freeze is only noticeable on my mobile, when I run the game on my laptop there is no delay on this line.

If I remove the shader from the assigned ShaderMaterial the freeze disappears.

Is this something to do with preload? should I preload this material?

Looks related to this. But the issue is closed :?

d2clon | 2023-06-30 17:21

:bust_in_silhouette: Reply From: d2clon

Looks like it is a known issue known as “Lazy shader compilation” that makes the shaders to be compiled in run time at the moment they are used the first time. It is solved in some cases but not for others:

Depends on the rendering engine or something that I am not able to comprehend properly.

The solution I see is recommended is, somehow, to make these Materials (Shaders) to be used when the game starts.

I have created this Autoload Script (https://gist.github.com/fguillen/2327f281c7827f39f7873550273fbe63) to do this job:

# Create a Scene with a Node
# Add this script to it
# Add the Scene to the Autoloads
# Fulfill the material Array with all the Materials that are causing freeze

# preload_materials.gd
extends Node

# Load the array through Inspector
@export var materials: Array[Material]


func _ready():
	_load_materials()
	

func _load_materials():
	var sprites = []
	for material in materials:
		var sprite = Sprite2D.new()
		sprite.texture = PlaceholderTexture2D.new()
		sprite.material = material
		add_child(sprite)
		sprites.append(sprite)
	
        # Remove the sprites after being rendered
	await get_tree().create_timer(0.2).timeout
	for sprite in sprites:
		sprite.queue_free()

Fulfill the Array[Materials] through the inspector

It also works from Material from a ParticlesSystem that was also causing lag in my game.

I have seen other solutions, in case my one is not working for you: