Jump to content

2D text in world space.


Recommended Posts

I am trying to do dynamic 2D text rendered in world space. I have seen old posts related to this:

However, these seem to be based on deprecated functionality.

I have used AdvancedDynamicTexture.CreateTextureForMesh() with planes, but I have achieved non-ideal results in terms of text clarity/clipping/stretching (due to varying text lengths) ((also probably due to my ignorance)).

Did the WorldSpaceCanvas2D functionality disappear with Canvas2D? Coming from Unity development 'world space' and 'canvas' are comforting words.

If there is any functionality in BABYLON.GUI that I am missing I would greatly appreciate a point in the right direction.

Thank you.

Link to comment
Share on other sites

Hi Jeke, welcome to the forum.  You're not doing anything dumb... not at all.  It takes some time to get-familiar-with the newest GUI system in BJS.

First, let me show you a playground... which DOESN'T really use "world space"... but uses screen space.

Follow along with http://doc.babylonjs.com/how_to/gui

Here's the PG:


Is THIS kind of labeling... ok for you?  You can also have lines... connecting the labels to targets/linked-with mesh.

You can also have "rects' surrounding each textBlock... which gives you borders, as wanted.  thickness property is not active for textBlocks.  Some programmers use an un-pickable GUI simplebutton to automatically wrap a thickness-active GUI rect... around a textBlock.

Anyway, let's start with the above playground... and see if you could work-with THAT type of full-screen GUI labeling.

Also, textBlocks have textWrapping abilities, so maybe THAT could be useful, too.  To activate textWrapping on the textBlock of a simplebutton, you might need to use...

mySimpleButton._children[0].textWrapping = true;  I'm not SURE that will work, but maybe. 

Take a look, goof around, see what you think.  Report back if you wish, and maybe 'ping' me... like this... @Wingnut  (in comment editor, type @ and then maybe wi, and then you can select my name from a drop-down list of names).

Anyway, I hope I have been helpful.  We CAN go-back to 'planes & billboardMode method' ... if this full-screen ADT method... doesn't work for you.  We might be able to make that work ok, too, with a little tweaking.  This way is easier, though.  :)

PS:  I HAD TO change the colors on the inputText.  Black letters on white background... don't work so well.  I needed to swap the colors.  This MIGHT be a small core bug... not sure.

Link to comment
Share on other sites

@Wingnut thank you for the reply. These forums have been extremely helpful in getting up to speed with BabylonJS. It is a very pleasant environment.

I am working to essentially remake some existing software in BabylonJS (since it has unbelievably faster load times than Unity WebGL builds). So I am trying to re-create it as faithfully as possible, but I had conceded the world-space labels for screen-space labels like the ones you showed.

I just figured I would post on the forum and see if I was missing some "easy win" for world-space labels.

I am starting to see a reoccurring trend of having issues dealing with dynamically sized text in GUI elements. From digging around in these forums GUI infrastructure design/work seems to be a rabbit hole.

Maybe someday I can contribute to that, but that seems like it would be far off.


Link to comment
Share on other sites

Hello and welcome @jeke

regarding your initial question, you have to keep in mind that the worldspace GUI will use a texture and the texture has a defined size (1024x1024 in your sample)

So even if we support autoStretchWidth, you cannot go bigger than the texture resolution

So in your case you have to either educe the font size so container will not go bigger than 1024: http://www.babylonjs-playground.com/#M50WUZ#5

Or you can leverage the textWrapping property of the TextBlock: http://www.babylonjs-playground.com/#M50WUZ#6



Link to comment
Share on other sites

@Deltakosh Thank you for the reply.

Yep, I realize that I would have to do something fancy to maintain appearance and resolution (per character). One option I had considered was using a monospaced font and using multiple textures for longer labels, but hopefully the screen-space labels are acceptable.

While you are here, am I missing some functionality of GUI/TextBlock where text could have a fixed width and an adaptive height?

I guess one could do something hacky with measuring text and inserting newline characters into a text block that has resizeToFit set to true.

Link to comment
Share on other sites

35 minutes ago, Deltakosh said:

Who do you see it working? Injecting adapted empty lines?

If you mean like this: https://www.babylonjs-playground.com/#XCPP9Y#559 then yes, but more fancy.

I can make do with what is available now. The existing code-base is greatly appreciated.  

Is more complicated GUI infrastructure high or low in the priority list? (or does just no one want to tackle it?)

Thanks again for the time.

Link to comment
Share on other sites

Hi guyzzz. 

The current GUI stackPanels work great.  I don't understand your concerns, jeke.

You can push/pop textBlocks into/from an isVertical stackPanel... FOREVER.  They work great.  Keep monitoring their ._children... copy entire "packages" of ._children from one container to another... so easy.  (we recently, near-seamlessly... changed a scene from full-screen gui, to texture-on-a-plane-gui, and back again.  SO cool!)  Its a plane, its full screen, its a plane, its full screen, back and forth... I LOVE IT!  (Good for flying-in/out GUI panels... like kites.)

I think you are suffering from un-familiar-ism, jekester.  :) Give yourself some time to play with the new toys.  heh.

We're missing overflow/scrollbars, but... look at Arte's cool scrolling listview:  https://www.babylonjs-playground.com/#08KEYA#32 

Mousewheel active, vertical slider active (they said we couldn't do the vertical slider but we defied physics and did it anyway!)

That is an .isVertical=true stackpanel, full-of isVertical=false stackpanels...  with a "what's showing now" manager.  No need for overflow/scrollers, we can make our own scroll widgets and handle our own overflow.  Stack-Masters!  :)

Each one of those horizontal stackpanels (each row) COULD be a big fat textWrapped textBlock... with special background coloring (and/or borders) to separate it from OTHER textBlocks in the big stack of (rect-bordered) textBlocks.

Really, the sky is the limit... with BJS GUI.  You can modify it on-the-fly SO EASILY... twist and bend it, make your own widgets... it's pretty fun and powerful.  Ya just gotta 'ease' into it.  :D

Take it out to dinner... have some wine, tell some jokes... get to know it.  In various parts of the forum, we have been experimenting with building our own GUI controls... rather complex ones, too.  Like a meterControl, dialControl, dragpuck, and ipod control... demented experiments based on the colorpicker control.  If you ever want to "go deep" in GUI widget-making... we got the goods.

Yep, me thinks ya need some cuddling-up to stackPanels and other containers.  They work pretty nice... I think you will find they can get the job done.

Link to comment
Share on other sites

I completely agree with you on the unfamiliarity @Wingnut. I'm sure with more time I will be able to craft more complex GUI layouts that would fit my needs.

I think my specific issue lies with having more control when dealing with arbitrarily sized text fit around other fixed UI elements (something my application works with constantly) ((something we could also change the design to avoid)).

If you can master-craft a TextBox with a fixed width, that can be filled with an arbitrary length of text and have another UI element (say a button) directly bellow the text, then I would be set!

I appreciate all of the feedback, and I certainly plan to keep learning this framework. Thank you.

Link to comment
Share on other sites

*nod*  Yeah, when you say "arbitrary sized text"...  do you mean both text-length and font-size/family?

ScaleToFit-like things get SOME features, but... I suppose a new container/rect is needed... an overflowContainer.

The https://www.babylonjs-playground.com/#08KEYA#32 panel is pretty close to accomplishing that.

I think idealHeight could get involved here, too.  Not sure, but I have seen that property name pop-up here and there.  We can read the docs.

Let's say you have a fixed-size rectangle that you want to make ALL your text fit-into.  It never stretches, so it can be counted-on to behave predictably...  when positioned among other GUI controls (usually done by putting nearby/adjacent controls into vertical/horizontal stackpanels... for proper share-the-space considerations.)  Keep in mind that stackpanels can contain many different TYPES of controls, including OTHER stackpanels or containers holding stackpanels, ... all in the same stackpanel.  It's an untamed frontier!  ;)

Now, how do we power-up that rectangle/container control... to make it overflow-smart?  Good question/challenge!  I love it!

First thing would be "sensing" an overflow condition... and let's assume we are ONLY talking about vertical overflow.  textWrapping will take care of horizontal overflow.

Once you have that... anything is possible.  First thing (upon sensing overflow) might be to activate a vertical slider along the side of the rect.  Ideally, keep the fixed-size rect the same width... after adding the slider.  So you add the slider to the inside-area of the rect.... and re-textwrap (reflow the text). 

But we have vertically-overflowed, so... each line in text._lines array... might need to be put into a textBlock of its own, and added to a stackpanel. 

Suddenly, your simple rect... becomes a one-textline-per-stackpanel-child... "manager".  If 100 lines of text got put into this rect... the rect senses it and becomes smart enough to change itself into a vertical-slider-driven stackpanel manager.  It checks the height of each textBlock line, and knows how many is the maximum it can display in its "view area".  In other words, you can't make it screw-up, no matter the amount of text, and no matter the font-size (within reason).  That would be cool, huh?

And then ideally, if the 100-lines-of-text is removed, and a little one-word line of text is displayed instead, the smart-rect turns back into a simple rect... with no stackpanel child... becoming "normal" again.

Custom overflow handling.  It might be fun just to try to find a good "sensor".  Keep feeding long text into a short-height rect, and use the renderLoop to "listen"-to (monitor) various properties on the rect control that surrounds it.  See if you can somehow "see", programmatically... when the height of the textblock exceeds the (ideal?-) height of the rect/container.  See if you can sense overflow.

And if you or another forum user DOES do these tests.... please share, eh?  I'm very interested in learning-about and helping dev an overflow-sensing rect/container.

"measurement" stuff is found on rects and their root containers and superClasses.  These measurements are sometimes/often/always established at CREATION-time, but are not necessarily live-updated, and may need control._markAsDirty() calls to get "reflows".  And these are not HTML-like reflows... so... expect the unexpected.  Even after markAssDirty()  [sic] calls, these measurements might not change.  But they might.

One interesting test... would be to keep changing font sizes, so the textWrapping has to keep re-wrapping, and thus the textblock height measurement is changing all the time.  Try to get a flag active... rect.isOverflowed true or false.  Perhaps... create a custom observer/notifyListeners system... (see observer docs) around your new sensor. 

Perhaps Arte's #32 scrolling stackpanel would be a good playground to strip-down, and convert into the "auto-sensing, overflowed-by-text, container-testing playground", eh?  It already has a working vertical slider with active mousewheel... to turn on/off.

Arte's mousewheel works ANYWHERE on the screen, but I think it would be cool if the mousewheel scroller ONLY worked when mouse pointer is hovering the control-to-be-scrolled.  That would be important IF you had MANY overflowed rects/containers... on-screen at the same time.  The mousewheel would need to know WHICH overflowed rect to scroll.

https://www.babylonjs-playground.com/#08KEYA#33  There is a playground with a GUI rect source code... inserted into the playground.  We can easily make modifications to it... in that playground... to make it "observe" when it has vertically overflowed.   Scary-but-fun hacking!  Might we need the superClass... GuiControl, in the playground, too?  We can "borrow" whatever code is needed... from https://github.com/BabylonJS/Babylon.js/blob/master/dist/gui/babylon.gui.js

Just some thinkin'.  I hope Deltakosh, Adam, Arte, Jeke, and all other wise/inventive forum-folk... add comments and have more ideas. 

Link to comment
Share on other sites

Hi guys.  https://www.babylonjs-playground.com/#08KEYA#38

There's a tester. 

In lines 428-438, I create text3... with a substantial amount of text.

In lines 446-455, I increase the fontSize of text3... every 2 seconds, and do some console reporting... monitoring text3 and contentRect ._currentMeasure.height values.

Watch console.  These values are NOT changing, no matter the fontSize.  So ._currentMeasure.height is not a good property to monitor...  for an overflow sensor.  :)

We'll keep looking, and maybe look at some source code, and perhaps listen for hints and help from others.  :) Sorry for the messy playground, but I wanted to keep SOME of that "stackManager" code in there... so we are ready to experiment when we DO find a good overflow sensor.

And yes, we COULD just use text3._lines.length as a "sloppy" overflow sensor:  If (text3._lines.length > howManyAllowedLinesInViewableArea) [let's imagine it's 6], then contentRect.isOverflowed = true.  BUT... that does not take fontSize into consideration.  With a LARGE fontSize... 3 lines of text COULD overflow the 6-linesAllowed viewing area.  Thus, this method of height-overflow sensing... is not "bulletproof".

Link to comment
Share on other sites

Nice test @Wingnut.

I agree that the string length has way too many shortcomings to be a solution.

I will dig around and see if we can find any source for how other platforms handle rect sizing with dynamic text content.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...