extends Spatial #This script loops through all the nodes in the scene, finds their materials, #then adds them to a generated quad mesh to force all shaders to be compiled. #Once they are all compiled, the node emits a signal saying it's done and frees itself. #This is to prevent frame stutter when compiling shaders mid-game. #If you need to compile a material that is not present #when the scene loads (i.e. instanced nodes) add a copy of their .tscn as a child of #this node in the scene window. #This spatial node must be placed somewhere within the camera's frustum. It does not have #to be directly visible, it can be under a floor or behind a wall, as long as it stays #within the camera frustum bounds for the amount of frames specified below. signal all_shaders_compiled const num_frames = 10 #How many frames the script runs for. var found_materials = [] var found_particles = [] var counter = 0 func _ready(): compile_shaders(get_tree().root) func _process(_delta): counter += 1 if counter >= num_frames: emit_signal("all_shaders_compiled") queue_free() func compile_shaders(scene): for child in scene.get_children(): if child is MeshInstance: for i in range(child.get_surface_material_count()): var mat = child.get_surface_material(i) if mat == null: mat = child.mesh.surface_get_material(i) if mat == null: print("Error: No material assigned to " + str(child.name) + ". Could not compile.") if is_instance_valid(mat): if not mat in found_materials: generate_quad(mat) found_materials.append(mat) if child is Particles: var particle = child as Particles var particle_mat = particle.get_process_material() if particle_mat == null: print("Error: No process material assigned to " + str(child.name) + ". Could not compile.") if is_instance_valid(particle_mat): if not particle_mat in found_particles: var particles_to_compile = particle.duplicate() duplicate_particles(particles_to_compile) found_particles.append(particle_mat) compile_shaders(child) func generate_quad(material): var quad = QuadMesh.new() var mesh = MeshInstance.new() mesh.mesh = quad mesh.set_surface_material(0, material) add_child(mesh) mesh.global_transform.origin.x += randf() * 0.5 mesh.global_transform.origin.y += randf() * 0.5 mesh.global_transform.origin.z += randf() * 0.5 func duplicate_particles(particle_node): particle_node.translation = self.translation particle_node.rotation = Vector3.ZERO add_child(particle_node)