How to render multiple scenes without using multiple threejs contexts

Viewed 564

I've seen this tutorial on how to use only one threejs context and renderer to display objects on multiple canvases, is there any way to migrate the result to react-three-fiber. There is an exemple of multi scene on github but it's not what I want.

I've came up with something like:

import React, { useMemo, useEffect, useRef } from 'react';
import * as THREE from 'three';

function useRenderer() {
  const renderer = useMemo(() => {
    const canvas = document.createElement('canvas');
    return new THREE.WebGLRenderer({canvas, alpha: true})
  }, []);

  return renderer;
}

function Scene({ renderer }: any) {
  const ref = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    if (ref.current) {
      const {left, right, top, bottom, width, height} = ref.current.getBoundingClientRect();
      const isOffscreen = bottom < 0 || top > window.innerHeight || right < 0 || left > window.innerWidth;
      const ctx = ref.current.getContext('2d');

      if (ctx && !isOffscreen) {
        const rendererCanvas = renderer.domElement;

        if (rendererCanvas.width < width || rendererCanvas.height < height) {
          renderer.setSize(width, height, false);
        }

        // make sure the canvas for this area is the same size as the area
        if (ctx.canvas.width !== width || ctx.canvas.height !== height) {
          ctx.canvas.width = width;
          ctx.canvas.height = height;
        }

        renderer.setScissor(0, 0, width, height);
        renderer.setViewport(0, 0, width, height);

        // copy the rendered scene to this element's canvas
        ctx.globalCompositeOperation = 'copy';
        ctx.drawImage(
            rendererCanvas,
            0, rendererCanvas.height - height, width, height,  // src rect
            0, 0, width, height);                              // dst rect
      }
    }
  }, [ref, renderer])

  return <canvas ref={ref} />;
}

function App() {
  const renderer = useRenderer();

  return (
    <div>
      <Scene renderer={renderer} />
    </div>
  );
}

export default App;

But I feel like I'm getting out of react and react-three-fiber and I don't know how to render children of my Scene.

Any way I can achieve this without being too dirty?

0 Answers
Related