Multiple canvas multiple scene, each controllable

Hello, I am new to BabylonJS and still trying to learn.
Currently I am trying to do following task:

  • Have an array of mesh
  • Iterate through mesh and create a scene for each mesh on a different canvas. And each scene is controllable independently. (Drang, zoom, translation, etc)
  • Want to use react-babylonjs (If too tricky, i’m willing to switch to non-react syntax(?)… in such case, example code would be super helpful)

btw, if there is a way to write react-babylonjs style code into a PG, please let me know.

I have referred to multiple posts in the forum and documentation as well as react-babylonjs issues. Haven’t been able to figure out best solution yet.

I expect to see something similar to this page. But each canvas holding different scene with different mesh. And all canvas controllable.

Here is where I am so far.

{isLoaded ? (
          <React.Fragment>
            <Engine
              canvasStyle={{ width: '100%', height: '100%' }}
              antialias
              adaptToDeviceRatio
              observeCanvasResize
            >
              <BabylonViewer
                fileInfos={[...commonFiles, uniqueFiles[0]]}
                canvasRef={canvasOneRef}
              />
              <BabylonViewer
                fileInfos={[...commonFiles, uniqueFiles[1]]}
                canvasRef={canvasTwoRef}
              />
            </Engine>
          </React.Fragment>
        ) : null}
        <div className="grid">
          <div
            className={`relative rounded h-40 w-80`}
          >
            <canvas ref={canvasOneRef} />
          </div>
          <div
            className={`relative rounded h-40 w-80`}
          >
            <canvas ref={canvasOneRef} />
          </div>

Inside BabylonViewer component:

return(
     <Scene clearColor={new Color4(1, 1, 1, 1)}>
        <Suspense fallback={<box name="tmp"></box>}>
          <MeshLoader
            name={`meshLoader`}
            fileInfos={fileInfos}
            onLoadHandler={setMeshLoaded}
          />
        </Suspense>
        <arcRotateCamera
          ref={cameraRef}
          name={`camera`}
          alpha={0} //{Math.PI / 2}
          beta={0} //{Math.PI / 2}
          radius={10}
          target={Vector3.Zero()} //{new Vector3(0, 0.5, 0)}
          minZ={0.1}
          lowerBetaLimit={-Number.MAX_VALUE}
          upperBetaLimit={Number.MAX_VALUE}
          allowUpsideDown={true}
        />
        <pointLight
          name={`light`}
          intensity={0.9}
          position={Vector3.Zero()}
          direction={new Vector3(0, 0, -1)}
          specular={Color3.Black()}
        />
        {canvasRef && canvasRef.current !== null && (
          <engineView
            target={canvasRef.current}
            camera={cameraRef.current as Camera}
          />
        )}
      </Scene>
)

I referred to Support for multiple views rendering multiple scenes · Issue #136 · brianzinn/react-babylonjs · GitHub this issue to write above code.

Issue with the codes above is that I only want canvasOneRef canvasTwoRef to render but the <BabylonViewer> also renders on its own canvas. → Meaning I get total four screens. Two from <BabylonViewer> which I can control, and the other two on <canvas> where I add view.

Can someone help please… Would really appreciate y’all’s help :pray:

Adding @brianzinn the wizard behind babylonjs-react to see it it is supported ?

1 Like

About where to post the code, I have used https://codesandbox.io to ask questions about babylon react before, and it works great :smiley:

1 Like

There are a few different ways to approach. Easiest way is to have an Engine for each Scene and loop your models to make scene + engine. That will perform OK with 2 models, but degrade as you add more. You can use a prop where the scene will only render if it is visible on the screen (ie: if you scroll out of view it’s not rendered) to make it perform better.

I have a new PR this morning that may be useful if you want to render multiple engines on-screen simultaneously:
Render on Demand by dennemark · Pull Request #253 · brianzinn/react-babylonjs (github.com)

You can use EngineView component like how your linked example and react-native Babylon.js:
Babylon Basic - Engine View ⋅ Storybook (brianzinn.github.io)

But I think the example doesn’t refer to what you actually want to do, because you also said you want different scenes.

You can also use views like here:
Babylon Basic - Viewport ⋅ Storybook (brianzinn.github.io)

You can share scenes on an Engine and show one at a time:
Babylon Basic - Toggle Scene ⋅ Storybook (brianzinn.github.io)

You can register more canvases on the Engine like this:
kencyke/react-babylon-multicanvas (github.com)

There are a few ways to go about it - even portals to other canvases, etc. I think it’s better to get a working PG or repo even imperative (but I haven’t seen PGs with multiple Scenes)… and then work backwards.

3 Likes