Any way to make GUI resize more exact and faster?

Does anyone have any thoughts on how to make this GUI rectangle resize more exact (exactly the width of the mesh) and/or faster on camera zoom?

In the above example it isn’t super easy to see but the rectangle actually becomes wider than the mesh at certain zooming. It is more evident in this video (around second 20):

This video is of a React-three-fiber solution that seems to do a much better job scaling the text during zoom:

I’m new to Babylon and 3D programming in general so these questions maybe not well thought out but:

  • Is GUI the right tool? Would this perform better if the text were a mesh? If so, how does one get a resizable text mesh in Babylon?
  • Is measuring the mesh the slow part? I’ve fiddled with coming up with the offsets solely based on the camera radius but no real luck.
  • Is there a way to keep the camera zoom and text resize in sync? Basically prevent the zoom until the text has been resized?

This is a follow up of this post: How to do GUI like text but expanding - #7 by msDestiny14

Ooh I remember making that resizing function, guess it still needs some more work or maybe another approach thou. :slight_smile: Here’s an update to it using relative radius to more quickly calculate the updated width and offset of the GUI rectangle… It still seems laggy (maybe a bit better thou?) and still the width will sometimes end up being a little off… IDK what the fix is thou. :thinking:
PG: https://playground.babylonjs.com/#XCPP9Y#11065

Actually, now that it’s updating faster, doing it on the before render observable helps cut down the lag more it seems… :slight_smile:
PG: https://playground.babylonjs.com/#XCPP9Y#11066

3 Likes

Yeah, that’s better but still laggy:

Is there no way to keep the updates in sync? Really appreciate the help!

1 Like

Hey guys!
So I was curious what is happening here. I changed this value and made a video while I was using my “rattlesnake” wheeled mouse :smiley: specially connected it for this video so you have audiovisual feedback.

    camera.wheelDeltaPercentage = 0.02

Video here (sorry for the background sounds, it’s an air purifier :smiley: )
https://misc.babylonjs.xyz/a.mkv

Do you think it’s better?

1 Like

The lag seems most noticeable when zooming quickly so limiting the speed def helps IMO. :+1:

1 Like

It looks like forcing the texture to update by calling _checkUpdate like below fixes the lag (almost completely?), I couldn’t find a way to do it with public functions/properties thou…

2 Likes

Also it seems like maybe the width is correct but the x position is wrong. :point_down:

1 Like

That’s awesome! Seems to solve the issue! Out of curiosity, is there a reason why checkUpdate is private? Also, I don’t suppose you are available for paid consulting? Check out Moss!

1 Like

Hmmm that’s weird but seems like a much more solve-able issue than the lagging update. Really appreciate the help!

2 Likes

I think since it’s already called each frame it shouldn’t need to be called manually, but in this case that’s the only way I could find to get the timing right… :thinking: (Edit: well, other than overriding the ADT constructor to use a different observable for the update).

PS thanks for the offer but I prob wouldn’t be able to be available very often RN. :slight_smile:

Lol guys I’ve just realised (after putting on my glasses and checking the videos and PGs here again) that you were talking about the issue with the textbox alignment timing issue. I didn’t see it before without my second pair of eyes :roll_eyes: :see_no_evil: That’s why I created that PG with the video.

I was working on this PG and had the same problem with resizing the textboxes with a correct timing (code already removed from the PG)

Sorry :slight_smile:

So of course I implemented the suggested fix and everyone was happy for about a minute until complaints about drastic drop in frame rate when doing a fast zoom. I think in order to keep the frame rate up we will probably have to hide the labels when zooming fast then show them.

Do you happen to have any suggestions?

Oh no, I bet it’s because the GUI is updating twice per frame while zooming, which was the only way I could find to keep it in sync. It makes sense thou with more controls on your actual site it would have a bigger impact… :frowning_with_open_mouth: Tomorrow or next day I can investigate a little more and will post if I discover anything. :slight_smile:

So I found that forcing the root container to do an extra layout seems to keep the GUI in sync just as well, which is much less processing than doing the full update. I’m still not sure why it’s needed thou or what a better/faster way to keep the GUI in sync while zooming would be… Maybe someone else will have more ideas about it but I’m getting stumped now. :slight_smile:

REALLY APPRECIATE the help! This change does improve the performance while keeping the GUI mostly in sync. There is some noticeable delay but much better than the original if not as good as the force update…

What is interesting is if I remove the textWrapping the performance improves even more (we have lots tiles with the GUI labels underneath) which I guess is to be expected…

1 Like

Hey @Matthew_Pflueger @Blake,

@bghgary did some awesome debugging work and helped us narrow down the source of this issue. It looks like _processMeasure needs to be called whenever the view matrix changes. (it’s already called by _checkUpdate in onBeforeSceneRender, but for some reason it needs to be called even earlier than that to keep it in sync.) I made a couple of changes to one of the playgrounds:

Simple GUI in fullscreen mode | Babylon.js Playground (babylonjs.com)

The main thing is that all we need to do is call _processMeasures on the rect to keep it in sync, rather than needing checkUpdate on the whole ADT.

We definitely want to fix this issue in Babylon GUI, rather that needing a workaround that calls internal functions. I am going to take a look into this further and hope an update by Monday :slight_smile:

2 Likes

This is cool!

1 Like

Just a quick update: we are still investigating the right fix. This issue is harder than we expected - we don’t know yet why _processMeasures resolves the problem. It is definitely in progress, but no update yet.

Poked around and narrowed it down a little more too I think: it seems calling _measure() works just as well as calling _processMeasures(), which calls _measure() among other things…

Also wanted to point out thou that a test PG with more controls might be needed, since calling _checkUpdate was needed to fully keep everything in sync when used in production with lots of controls…

1 Like