endWithComposite() {
    const gl = cc._renderContext;
    const { shaderCache } = cc;
    const needsCache = this.getScreenCacheRequested();

    if (this._redirectingToScreenPass) {
      this._redirectingToScreenPass = false;

      // stop redirecting drawing to screen pass
      this.passes.screen.endWithReset(this._postProcessingRenderPassStackId);

      if (needsCache) {
        this.passes.cache.beginWithResetClear(this._postProcessingRenderPassStackId);
      }

      // blur screen
      if (this.getIsBlurringScreen()) {
        // blur: horizontal pass
        this.passes.blur.beginWithResetClear(this._postProcessingRenderPassStackId);
        const blurProgram = shaderCache.programForKey(this.screenBlurShaderProgramKey);
        blurProgram.use();
        this.setRenderPassMatrices(blurProgram);
        blurProgram.setUniformLocationWith1f(blurProgram.loc_xStep, 1.0 / this.passes.blur.width);
        blurProgram.setUniformLocationWith1f(blurProgram.loc_yStep, 0.0);
        cc.glBlendFunc(gl.ONE, gl.ZERO);
        cc.glBindTexture2DN(0, this.passes.screen.texture);
        this.passes.blur.render();
        this.passes.blur.endWithReset(this._postProcessingRenderPassStackId);

        // blur: vertical pass
        this.setRenderPassMatrices(blurProgram);
        blurProgram.setUniformLocationWith1f(blurProgram.loc_xStep, 0.0);
        blurProgram.setUniformLocationWith1f(blurProgram.loc_yStep, 1.0 / this.passes.blur.height);
        cc.glBlendFunc(gl.ONE, gl.ZERO);
        cc.glBindTexture2DN(0, this.passes.blur.texture);
        this.passes.screen.render();
      } else {
        var posTexProgram = shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE);
        posTexProgram.use();
        this.setRenderPassMatrices(posTexProgram);
        cc.glBlendFunc(gl.ONE, gl.ZERO);
        cc.glBindTexture2DN(0, this.passes.screen.texture);
        this.passes.screen.render();
      }

      if (needsCache) {
        this.passes.cache.endWithReset(this._postProcessingRenderPassStackId);
        this._startCachingScreen();
      }
    }

    if (this._cachingScreen) {
      // draw cache
      var posTexProgram = shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE);
      posTexProgram.use();
      this.setRenderPassMatrices(posTexProgram);
      cc.glBlendFunc(gl.ONE, gl.ZERO);
      cc.glBindTexture2DN(0, this.passes.cache.texture);
      this.passes.cache.render();
    }
  }
Composites redirected drawing.
NOTE: This should be called automatically at the end of the frame rendering phase.