summaryrefslogblamecommitdiffstats
path: root/utility_scripts/shader_compiler.gd
blob: 7ef61041be582ba7ce6e4b9322a4911113b1c064 (plain) (tree)













































































                                                                                                                                   
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)