How to use multiple active cameras in RenderTargetTexture or MultiRenderTarget

Hi everyone, first time posting!

I’m trying to use an array of cameras in a scene, and then use RenderTargetTexture to render them onto a texture and then use it on a quad.
Here’s a link to a playground I created with the camera array I want: Babylon.js Playground
It works fine without RenderTargetTexture or MultiRenderTarget.
If what I want is actually render all the cameras with their viewport preserved into a texture and apply it somewhere else. So I tried to do that in this link: Babylon.js Playground
But as you can see in the link, only the last camera show up in the rendered texture.

Is there a way to have all the active cameras show up at the same time? Thank you all for helping!

Hi and Welcome to the forum!

https://www.babylonjs-playground.com/#LCHNNJ#4

Here are the things I have corrected:

  • You did not setup the mergeMaterial correctly as you did not bind the textures generated by the multiRTT. See lines 186, 189 and 190
  • The multiRTT should be added as a custom render target to each subcamera and not for the whole scene. If set only for the scene, a single rendering will be done. As you want a rendering for each camera, it should be added to subcamera.customRenderTargets instead (see line 70).

When doing this, it still does not work because the multiRTT is automatically cleared before each rendering, whereas you want it to be cleared once (before the first rendering).

To do this:

multiRenderTarget.onClearObservable.add(() => void(0));

scene.onBeforeRenderObservable.add(() => {
    multiRenderTarget._bindFrameBuffer();
    engine.clear(multiRenderTarget.clearColor || scene.clearColor, true, true, true);
    engine.restoreDefaultFramebuffer();
});

The first line add an empty observer to the onClearObservable event, which disables the automatic clearing of the RTT.

Then the remaining code clears the RTT once for each frame (each call to scene.render()).

_bindFrameBuffer() is not a visible function in intellisense, but it’s still public, so calling it is somewhat legal I guess…

If you feel bad calling _bindFrameBuffer(), you can check if the current camera is the first camera in multiRenderTarget.onClearObservable:

multiRenderTarget.onClearObservable.add(() => {
    if (scene.activeCamera === scene.activeCameras[0]) {
        engine.clear(multiRenderTarget.clearColor || scene.clearColor, true, true, true);
    }
});

https://www.babylonjs-playground.com/#LCHNNJ#2

1 Like

Thank you so much! I’ve been researching this for hours and couldn’t figure it out. Thank you!