public void render(GameBranch branch) {
        Window.bindAsRenderTarget();

        glClearColor(0f, 0f, 0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        branch.renderAll(forwardAmbient, this);
        for (BaseLight light : lights) {
            activeLight = light;

            BaseLight.ShadowInfo shadowInfo = light.getShadowInfo();
            getTexture("shadowMap").bindAsRenderTarget();
            glClear(GL_DEPTH_BUFFER_BIT);

            if (shadowInfo != null) {
                altCamera.setProjection(shadowInfo.getProjection());
                altCamera.getTransform().setPos(activeLight.getTransform().getTransformedPos());
                altCamera.getTransform().setRot(activeLight.getTransform().getTransformedRot());

                lightMatrix = biasMatrix.mul(altCamera.getViewProjection());

                setVector3f("shadowTexelSize", new Vector3f(1.0f / 1024.0f, 1.0f / 1024.0f, 0));
                setFloat("shadowBias", shadowInfo.getBias() / 1024.0f);

                Camera temp = mainCamera;
                mainCamera = altCamera;

                if (shadowInfo.isFlipFaces())
                    glCullFace(GL_FRONT);
                branch.renderAll(shadowMapShader, this);
                if (shadowInfo.isFlipFaces())
                    glCullFace(GL_BACK);

                mainCamera = temp;
            }

            Window.bindAsRenderTarget();
            glEnable(GL_BLEND);
            glBlendFunc(GL_ONE, GL_ONE);
            glDepthMask(false);
            glDepthFunc(GL_EQUAL);

            branch.renderAll(light.getShader(), this);

            glDepthFunc(GL_LESS);
            glDepthMask(true);
            glDisable(GL_BLEND);
        }
    }