GUI buttons no more working after changing cameras viewport

Hello everybody!

My game card is not optimzed (yet) for mobiles… it is playable, but everything is a bit too small.
So, instead of building something new, I had an epiphany: since I am in my camera time, I thought I could make an optimized mode with the screen split in two cameras, one zoomed at the cards in my hand and the second one at the middle of the play mate.

This could be amazing, balancing intuitively from one overall screen for general events, to the two focused cameras for the game.

Here it is before the split, in my browser simulating my Samsung Galaxy

When I click on “replace camera”, I:

  • add a second camera
  • give the existing camera and the new camera viewports that split the screen in two
  • point each camera at their respective target
  • call an engine.resize()

Here is what I obtain (I’ll adjust the light another time…)

And here are the related issues:

  • the 2d UI is deformed and no more clickable
  • the cards are no more clickable
  • the UI is displayed on both camera (for this one I think I have seen the solution on this very interesting blog from Dave Solares with use of layerMask)

I am missing something… thought an engine.resize() would do it…

Apparently all the 2d buttons on the right camera (the one that I added) are working.
Now I need to understand why they are distorted and also how to retrieve clickable cards on the left, first camera…

I’ll experiment with masks to keep the buttons only on the right and change the light…

Last remark, and sorry if I consolidate too many questions in one post: there are just the upper right buttons (expand, settings, close) that I would like to appear only on the second right camera and maybe a light that I would remove… I would like to keep all other meshes on both camera: is possible to do that ?
It looks like that as soon as I assign a layerMask to one of my camera, then meshes will belong to EITHER one of the camera (with the correponding layerMask) or the other, but never both of them…

Would you have a PG to share? Even just a simplified version? I believe your issue does come from the way you are handling cameras and layerMask. I also think this is totally achievable (but without the PG, I would need to reproduce it from scratch and I don’t really feel like it (sry).

I can however make a couple of assumptions for your issues:

Likely because it is expressed in percentage mode. When you resize your ADT to 50% of the width, controls are resized to the size of the container

Likely a layerMask and/or camera order issue.

Same as above. Although it could also be a pointerBlocker issue. Depends on how your ADT is built.

Again, layerMasks and camera controls are key here…

Edit: I fixed something similar just lately, may be it can help (else, as I said, give me the PG and I shall have a look at it)

There are also some more info for layerMasks in this post (and more to come in the doc soon to extend this section for ‘in-depth layerMask’)


You also have scene.cameraToUseForPointers to set the camera to use for pointer operations.

Okay, with your help, I am moving forward:

  • I understood thanks to one of your post, Mawa, that the order the cameras are added to the scene.activeCameras, matters, actually, crossing with what Evgeni_Popov wrote, I think the last camera added becomes the scene.cameraToUseForPointers
  • I understood thanks to deltakosh’s answer in this post that I can use AdvancedDynamicTexture.scaleTo to adjust the 2d controls: I ajdust it to the canvas size times the viewport size (which is in percent): this.advancedTexture.scaleTo(this.canvas.width*, this.canvas.height); and the result is good, no more distortion.

Almost there :slight_smile:

But now I would like:

  • to have the pointers on the cards working on the left camera
  • to have the menu buttons icons (settings, fullscreen, close): only displayed on the right camera and enabled…

Is this possible ? if only one camera at a time can use pointers, then I would remove them from the right camera and le them on the left one.

Finally, with the layerMasks: how can I keep all the meshes on both camera except these menu buttons ?

If no solution, I might go with an html div overlay, like the chat on the low left corner…

You can do something like this to draw the GUI only on the second camera and have pointer events working for both cameras:

For event handling, the PG simply sets cameraToUseForPointers to the correct camera based on the X position of the pointer.

For the GUI, it uses the layerMask property of the second camera and the GUI texture to be drawn by the second camera only.

1 Like

Thank you Evgeni,

The event handling part is very smart, never thought about it :slight_smile:

Regarding the GUI, I am missing something: I need the GUI only on the second camera, as in your PG, but I need also the rest of my meshes → as soon as I assign a layerMask to the second camera, then all my meshes will disappear until I specify the same layerMask which will then make them disappear from the first camera, no ?

You need to specify a camera layerMask like 0x1FFFFFFF => I think you missed the “FFFFFFF” part?

See the doc linked by @mawa (In-Depth layerMask | Babylon.js Documentation) for detailed information about layerMask.

Okay, sorry, I am a bit slow, I think I had an issue to understand the way the AND is calculated, everything is working fine, now!

Huge thanks to @Evgeni_Popov and @mawa

1 Like

@Evgeni_Popov maybe you would have another brillant idea for me: there is a light that is overlighting my second cam, any easy way to remove it from the cam ?

Can I use layerMask here too ?

You have several properties on a light that can help you: excludeWithLayerMask / includeOnlyWithLayerMask and includedOnlyMeshes / excludedMeshes.

The easiest ones to use are the “layerMask” ones, as you simply give a layer number to either exclude or include all meshes “intersecting” this layerMask.

1 Like

So, for the record, I spent several hours playing with lights, trying different types, combinations, positions, nothing worked really well, but then I took another approach, and tried to experiment with the specularColor of the different material involved which really produced good results.

Typically, play mates are often made of fabric which is not a shining material at all, so I went for this.tapis.material.specularColor = new BABYLON.Color3(0.2, 0.2, 0.2); , cards could be plastified, but mine are made out of cardboard :stuck_out_tongue: so specularColor = new BABYLON.Color3(0.4, 0.4, 0.4); (still to shiny, gonna try a bit darker).

And here we go, pretty hapy with the result, and if I would have done the game with a 2d framework, I would have had to rebuild a specific experience for small screen, here it is just a matter of adding a new camera: wonderful!

1 Like

Yes, on a standard material, specular can really help fixing direct light issues.
Rather than fixing the color though, you could have likely achieved something similar with the level of ‘specularPower’.

Thanks, I am going to do more experiences with the specularPower :slight_smile:

1 Like

Good, Just beware that the naming is in my opinion sort of incorrect. It should be specularDiffuse or something. The values are in fact inverted. The lower the value the stronger the light at the hitpoint.
The higher the value the more you are diffusing the light.