3D text in Babylon

The link below should have the same content as the link with the aged-out cert:
https://raw.githubusercontent.com/briantbutton/meshwriter/master/dist/meshwriter.min.js

jQuery seems unwilling to load a module from that URL, so I took advantage of having a small minified module and put it straight in the playground snippet. These playgrounds work.
https://www.babylonjs-playground.com/#PL752W#150
https://www.babylonjs-playground.com/#PL752W#151

I updated the links in github and npm to reflect those playgrounds.  Other playgrounds, I know they are out there, won’t work.

Looks like this thread is a little old, but I’m looking for a way to do dynamic 3D text. For example, display the current FPS in 3D on every render. Any way to do something like “setText” on a mesh created by MeshWriter?

I did a few experiments, like recreating the mesh on every frame, and nothing worked. Well, it does work but it completely destroys performance, so I assume it’s not intended to be used that way.

If it’s only for the fps, you should probably create 10 meshes for 0/1/2/…/9, clone each one 2 times and use them to display a number between 0 - 999.

1 Like

Evgeni published the same idea I had. Creating a glyph from a formula, and creating a texture out of it, it too resource intensive for such quick turnaround.

Perhaps you could also reconsider the objective just a bit . . . The FPS metric need not be faster than the eye can see and the brain can interpret. Some kind of a rolling average with a less frequent update will might be a way to go.

Well FPS was just an example of something dynamic. But your idea would work for everything else, also, right? I’d just need to create a mesh for each character that I might use in a string. I could do that step with MeshWriter, but then how would I go about getting the metrics for each glyph, so that I know where to position each consecutive mesh? I was actually just looking through the MeshWriter source trying to figure this out.

Pat, you seem pretty serious about this. (I mean that in a good way.)

The approach you described could be made to work, I think. One simplifying idea would be to use fixed-space font. I selected Jura font for displaying certain metrics, although I don’t expect anyone else to like it. If I recall, it’s numerals are all the same width.

I think Evgeni’s suggestion would work for variable-space fonts too. This is just a simplification.

Yeah, I’m serious! :slight_smile:

I really would like to have fast, dynamic, 3D text in my game.

So here is something that is getting really close. I studied what you did with MeshWriter, and did a lot of Googling, and I am now able to generate a 3D mesh in any font!

This just uses opentype.js directly, which is great because it also returns all the “metrics” data for each character. So I should be able to create a mesh for each character and just store the “advance width” and “kerning” and whatever else might be needed to build these strings dynamically.

Also, I have to give a huge thanks to “riv” on StackOverflow. His or her post here is what made this possible: javascript - Triangulate path data from OpenType.js using Earcut - Stack Overflow

3 Likes

One step closer!
https://playground.babylonjs.com/#IVGSG0#1
This now builds the text using an instance for each letter. If I can come up with a clever way to manage the instances, so that I don’t have to create/dispose them on every frame, then I think this will be done and will allow for fully dynamic, fast, 3D strings of text.

2 Likes

And here’s a fully working version, with dynamic text.
https://playground.babylonjs.com/#IVGSG0#2

It runs at 60 fps, even updating the text on every frame (which is probably overkill for most real-world apps).

Each letter that gets drawn is an instance. I create these instances as they are needed… For example, if you create the text "Hello, World" and then change it to "Hello again, World", only the "again" part has to be created, while the rest is just reused. But I never delete the unused letter instances if you later remove the “again,” for example.

If you want to actually use this, I would recommend:

  • Add opentype.js and earcut.js to your project the normal way and remove the hard-coded loader I used.
  • Add the font you want to use as a local dependency, e.g. "fonts/myGameFont.ttf", and remove the CDN hack I used just to get it to work in a playground.
  • Maybe delete unused letter instances after some amount of time, if you change the text a lot and have hundreds of instances sitting around unused.

Anyway, I hope someone finds it useful. I’ll be cleaning up the code and adding it to my project!

Edit: Moved this to its own topic – Fast, dynamic 3D text in any TrueType font

7 Likes

Please note that there is a new release of MeshWriter, 1.3.0, meant for projects that load part of the BABYLON library, not the whole thing, to save memory. Several folks have asked about this feature over the past year. @tibotiber finally got me over the energy threshold to do it.

It is out on github and also has been updated to npm.

This should have no affect whatsoever on current usage – it provides a new, optional way for parameter passing. See the new section at the bottom of the README for some more details. If this somehow (horror!) injects a new bug, please let me know post-haste!

Hasta!

6 Likes