RenderTargetTexture camera potential issues

I’ve been implementing a way of showing a scene from a different camera angle as a small overlay (could be used as a minimap, or to show a model from behind etc), and I’ve had a few issues with the way a RenderTargetTexture (rtt) currently works when using a different camera (to the main scene camera). Some of these may be bugs, others may just be implementation decisions, or some may even just be me not knowing a more correct way to achieve this.

The issues are explained in comments in the playground, but listed here below too:

  1. Must explicitly set renderList to undefined to get fallback, as it’s set in the rtt constructor to the empty list (so nothing rendered by default).
  2. The fallback only renders active meshes marked as such from the point of view of the scene active camera, not the rtt camera.
  3. All meshes in the renderList are drawn regardless of LayerMask or being out of view
  4. Disposing and recreating a mesh causes the rtt to not draw for a frame, but still clear the screen (if the list is set to undefined)
  5. If I want the rtt camera to behave similarly to the scene camera and calculate active meshes before render, I had to access a private method (scene._evaluateActiveMeshes)
  6. Using scene._evaluateActiveMeshes also requires a workaround to get instances that have their source mesh disabled rendering in both the main scene and the rtt.

I have what I need working as per that last playground (along with some additional functionality to only render when the camera properties change), but just wanted to highlight the above in case there’s something in there that should be addressed in a future update.

1 Like

Trying to answer some of the questions, but @sebavan may have more insight on some of the RTT design decisions.

I think the main purpose of RTT is to render a specific list of meshes given by the user. As such, the renderList property is an empty array to begin with and the user has to push the meshes to be rendered into the RTT.

Rendering all meshes into the RTT is not the primary goal, which is why it is not the default. It’s very possible that renderList = undefined was added afterwards as a fallback.

I assume this is by design, as we don’t want to evaluate active meshes for any other camera than the active one (scene._evaluateActiveMeshes is quite an heavy method).

Yes, since this list is user input, it’s the user’s responsibility not to push meshes that should not be rendered. As far as checking the layerMask property, this is something that can easily be added as the code is already there, so here’s the PR:

This is because removing a mesh clears the list of current active meshes. It will be rebuilt in the current frame but after the RTT has been rendered. So, by doing the removal in scene.onBeforeRenderObservable, you will get an empty list of active meshes when the RTT is rendered. You should do the removal after the RTTs have been processed, for eg. in scene.onAfterRenderTargetsRenderObservable.

This method is not meant to be called from the outside. If it is working for your use case, that’s ok, but it does a number of things that I’m not sure will work if you call it from anywhere, let alone an RTT pass…

If you’re just interested in whether the mesh is in the camera frustum or not, you should loop over the meshes and use mesh.isInFrustum() to build the list.

As explained above, this method should not be called from the outside and what you are experiencing is probably part of:

but it does a number of things that I’m not sure will work if you call it from anywhere, let alone an RTT pass

And thanks for the constructive comments (with PGs that get right to the point)!

yup it is sometimes required but might be so costly it is best to do explicitely but without list management.

yup that, I would assume as well.

Thanks @Evgeni_Popov and @sebavan, I’ll move to just checking in the frustum combined with that new mask property.

I guess this sort of things would usually be done using viewports, which I didn’t go with as I didn’t want to have to render the secondary camera every time the main camera is rendered. (I assume this is the case but didn’t really look into it too much; scissor test perhaps?)

Yes, if you use a second camera, it will be rendered every frame, so if you refresh the view less frequently, it is better to use a RTT.

1 Like