constructor(renderer, {
        parent,
        vertexShader,
        fragmentShader,
    } = {}) {
        this.type = "Program";
        if(!renderer || renderer.type !== "Renderer") {
            throwError(this.type + ": Renderer not passed as first argument", renderer);
        }
        else if(!renderer.gl) {
            throwError(this.type + ": Renderer WebGL context is undefined", renderer);

            // return if no gl context
            return;
        }
        this.renderer = renderer;
        this.gl = this.renderer.gl;

        this.parent = parent;

        this.defaultVsCode = this.parent.type === "Plane" ? planeVS : shaderPassVS;
        this.defaultFsCode = this.parent.type === "Plane" ? planeFS : shaderPassFS;

        // use the vertex shader specified or fallback to a default one
        if(!vertexShader) {
            if(!this.renderer.production && this.parent.type === "Plane") {
                throwWarning(this.parent.type + ": No vertex shader provided, will use a default one");
            }

            this.vsCode = this.defaultVsCode;
        }
        else {
            this.vsCode = vertexShader;
        }

        // use the fragment shader specified or fallback to a default one
        if(!fragmentShader) {
            if(!this.renderer.production) {
                throwWarning(this.parent.type + ": No fragment shader provided, will use a default one");
            }

            this.fsCode = this.defaultFsCode;
        }
        else {
            this.fsCode = fragmentShader;
        }

        this.compiled = true;

        this.setupProgram();
    }
Program class that creates, compiles and links the shaders
 Use a cache system to get already compiled shaders and save some CPU
 Also responsible for the creation, setting and updating of the uniforms (see Uniforms class object)

 params:
 @renderer (Renderer class object): our renderer class object

 @parent (Plane/ShaderPass class object): the mesh that will use that program
 @vertexShader (string): vertex shader as a string
 @fragmentShader (string): fragment shader as a string

 returns:
 @this: our newly created Program
*