summaryrefslogblamecommitdiffstats
path: root/godot3-prototype/utility_scripts/shader_compiler.gd
blob: 8048c8ae7ac2a2070a5bcdbea7b9f33b1f45b3ce (plain) (tree)
1
2
3
4
5
6
7


                                                                             
                                                                             

                                                                                       
                                                                  














                                                                                         
              
                                    

                      




                                           
                            



























                                                                                                           

                             








                                                   

                                        


                                                
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)