TypeScript

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>

CSS

html, body {
  margin: 0;
  overflow: hidden;
  width: 100%;
  height: 100%;
  position: relative;
}
.canvasWebGL {
  position: absolute;
  top: 0%;
  width: 100%;
  height: 100%;
}
.canvas2D {
  position: absolute;
  top: 50%;
  width: 100%;
  height: 100%;
}

JavaScript

var camera, scene, renderer, vp, stats;
var canv2D, texCopy;
var vec0 = new THREE.Vector2(0, 0);

var scene2 = new THREE.Scene();
scene2.add(
  new THREE.Mesh(
    new THREE.PlaneBufferGeometry( 12.6, 12.6 /* some ~tg(fov/2) here */ ),
    new THREE.ShaderMaterial({
      vertexShader: `
        varying vec2 vUv;
        void main() {
          vUv = uv;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }`,
      fragmentShader: `
        varying vec2 vUv;
        uniform sampler2D map;
        void main() {
				  gl_FragColor.rgb = 1.0 - texture2D( map, vUv ).rgb;
				  gl_FragColor.a = 1.0;
			  }`,
      uniforms: {
        map: { /* tbd */ }
      }
    })
  )
);

// Init WebGL stuff
function init() {
	// WebGL Renderer
	vp = new THREE.Vector2(window.innerWidth, window.innerHeight);
	renderer = new THREE.WebGLRenderer({antialias: true});
	renderer.setSize(vp.x, vp.y);
	renderer.domElement.classList.add("canvasWebGL");

	scene2.children[0].scale.x = vp.x / vp.y;


	// scene
	scene = new THREE.Scene();
	scene.background = new THREE.Color(0xe1e1e1);

	// camera
	camera = new THREE.PerspectiveCamera(35, vp.x / vp.y, 0.05, 100);
  camera.position.z = 20;
  
  // stats
  stats = new Stats();
	
	// torus
	const torus = new THREE.Mesh(
		new THREE.TorusKnotBufferGeometry( 2, 0.8, 100, 16 ),
		new THREE.MeshNormalMaterial()
	);
	scene.add(torus);

  // Make texture with Uint8Array as source
  texCopy = new THREE.DataTexture(
    null, vp.x, vp.y, THREE.RGBFormat
  );
  
  // append all to DOM
	document.body.appendChild(renderer.domElement);
  document.body.appendChild(stats.domElement);
}

function animate(s) {
	scene.children[0].rotation.set(
		s / 1000, s / 777, s / 1000
	);
  
  // Render scene to canvas
  renderer.render(scene, camera);
  
  // Copy canvas buffer to texCopy
  renderer.copyFramebufferToTexture ( vec0, texCopy, 0 );

  // Draw some cheap "next pass"
  scene2.children[0].material.uniforms.map.value = texCopy;
 ...