What is the best way to implement 3D text?

Hi,

I’m trying to implement 3D text that can be associated with a mesh, which the appearance looks like a 3D button. I’ve tried a few approaches but can’t get this work nicely. (2D GUI text is not what I’m after)

First of all, I tried to use GUI.Button3D (see this playground). It works somewhat nicely but I can’t find a good way to resize the button.
I tried to use button.scaling, it rescaled button width/height/depths successfully but the text content was stretched at the same time, which is not ideal. (The scaling is not working in this playground for some reason but it once worked.)

Then I used GUI.MeshButton3D (see this playground). I’m able to use a custom sized box mesh as button, however I can’t associate text as button content. In provided playground there’s only an empty box mesh (3D mesh button), no text is visible :cry:

I also tried to use MeshWriter, but I can’t position text properly on surface of the box mesh. See this playground.
Even I set text position to mesh position, it still sits somewhere inside the mesh. I also tried to set text x/y/z to other mesh relevant values, text still sits inside mesh :frowning_face:

At last I find the Dynamic Texture which seem to give me the best outcome so far. In this playground I created a box mesh then add text as dynamic texture. The only issue here though is it doesn’t support line break (\n character) or auto wrap of the text. Seems I need to manually split up a long string into multiple strings, then individually drawText each string like how this playground does.

I wonder if anyone knows the best approach to implement 3D text that can be attached to a mesh and also auto wrap? Or can be attached to a mesh and supports \n line break character?

Many thanks!


Updates:

In the end this playground is the best solution for my own project that has lots of scaling happing. The major approach is based on the marked solution answer.

In my other answer a bit further down this post has couple playground does similar thing but there’s no scaling, only width/height change.

Hope these playgrounds can help anyone encountered similar issue!

Thanks community for all the advice!

Hello! You can use the 2D GUI in texture mode: The Babylon GUI | Babylon.js Documentation (babylonjs.com) to draw wrapped text to any mesh :smiley: Wrapped text on mesh | Babylon.js Playground (babylonjs.com)

1 Like

Hello!

Thanks for the reply!

I actually tried that before, I noticed applying it as texture means text copy will be applied to all sides of the box mesh. Can I only draw text on one side of the mesh?
Also I noticed if I change box to different width and height, copy will be stretched rather than re-wrap the copy :thinking: See below playground:


Oh I actually figured I can bind 2D text to plane mesh, then set plane mesh parent to box mesh.
Position is nicely based on parent mesh position can make it only appears on 1 side of the box mesh.
Text wrap works nicely along with the advancedTexture.renderScale setting.

I hope my above approach is correct? Hopefully I’m not hacking anything :thinking:

Now I have a new issue, with dynamic texture drawText I can mix styles, like different colored text in one line (although it is tricky). But I can’t find a way to mix text colour using textBlock. Wonder if there’s a way to implement that using 2D textBlock?

That works perfectly fine! Another possible approach could be to pass custom UVs to each box face: Creating A Box | Babylon.js Documentation (babylonjs.com) so that only one face is mapped to the texture, but the plane works fine as well.

About different text styles, unfortunately that’s not possible as the text block is drawn as, well, a single block of text. You could get around it by having multiple text blocks, each one with its own style. There was a PR to introduce a StructuredTextBlock that would have this functionality, but it wasn’t completed, but you might want to take a look at the code to see how it’s done StructuredTextBlock (GUI 2D) by cronvel · Pull Request #11383 · BabylonJS/Babylon.js (github.com)

1 Like

Hi @carolhmj

Thanks for the StructuredTextBlock information, I will definitely give it a go.

I was trying to get this text texture working with scaled object last night. When parent mesh is a size 1 box mesh with scale that can’t constrain proportions, text will be stretched (which is expected). But for the project I’m working on I have to make text copy look not stretched and still fits into parent mesh visible part.

I figured out a workaround here: https://playground.babylonjs.com/#KBS9I5#28718

Wonder if there’s a better way to get this work?

i did a lot of experiments with meshwriter and also SPS to fill the outline of words. a number years ago. could do pretty much anything with it. some vids:

https://twitter.com/benrigby/status/1168936834547814400

https://twitter.com/benrigby/status/1169336849648803846

See thread here:

Hi,

Thanks for the info. Like I mentioned in original question, I did try meshwriter. It is very powerful but I struggle to get auto text wrap work with it. Is there a different build of meshwriter that can handle auto text wrap?

Here you can see text wrap:

I wrote the wrapping code. Can’t remember exactly what i did there, but it involved measuring the width and then redrawing when textwidth didnt fit the box.

Ah I see! That was actually our backup option.

However we wanted to avoid the manual calculation of mesh width to manually redraw text. I think 2D TextBox with AdvancedDynamicTexture works well with auto text wrap & text scale that our current project requires at this stage.

Thanks for the information though!

2 Likes