Hi all, I need to add some text in my threejs scene. I tried THREE.TextGeometry, CSSRenderer and troika-three-text package. But after some count, the performance is getting slow. I need to add nearly 100,000 text in my scene. Is there any better way to add text in three js, which doesn’t affect the performance?
But you won’t be showing all 100,000 words (characters) on the screen at the same time will you?
I think it would help if you could provide an example of what a typical page will look like.
For example, do you need 3D text floating in the air or just some kind of flat screen text?
Perhaps you need something that will read text from a text file and print it on the screen?
Or maybe a series of html pages?
now there’s pmndrs/uikit. maybe also buildwithflux/thomas which is used in flux.ai which has thousands of labels, but no layout.
both handle text and glyph instancing. uikit instances everything, even the ui with the addition that you have layout. it has a html → threejs converter in case you find it easier to style with css/tailwind, and a figma → treejs converter.
other than troika i doubt there’s much else in this regard. ui/text in threejs isn’t something that has seen much progress outside of react-three-fiber because large scale applications requiring such things are rarely if ever written in vanilla. though uikit is capable of running in vanilla with some limitations.
ps bela (the author) ran a test, 100.000 labels, 1 million glyphs. lots of triangles, but one draw call.
Yeah, I didn’t show all 100,000 texts at same time. But nearly 40 - 50 thousand texts will be shown at same time, based on the condition other texts will be shown.
Imagine something like this, My page has many meshes, each element has a name. I need to show the text near the element.
Please refer to the picture above posted by @drcmda in terms of readability of that amount of text on the screen on any reasonable resolution. Throwing 50k labels on the screen without optimisation will unnecessarily kill performance - as most of these labels will have sub-pixel size and can be approximated by a point instead.
(As for performance overall - everything three-related currently uses pretty much the same SDF approach troika introduced - that includes both the original troika, the uikit, drei, and all else. So performance-wise all solutions are going to have pretty much the same baseline.)
That’s too much for any human to read. For ultra high-definition displays, 50000 non-overlapping texts would mean 165 pixels per text (if you have nothing else besides the texts). My expectation is that you need at most a few hundreds of recognizable texts (the closest to the camera), and all the rest could be just merged into a soup of pixels.
Anyway, you may have a look at @prisoner849’s work:
So something like a display of the planets where there is a label by each planet and when you click on the label, you get a longer description of the planet?
I think I’ve seen an example of that recently in someone’s sample portfolio.
There are several ways to make 3D text:
- Geometry-based letters (with depth or flat) - Probably the slowest method, but the only way to create text with depth. There are official three.js examples of 3D text with depth or flat. The advantage is that you already have fonts and a mapping system.
- Transparent textures on a transparent plane (the old standard) - You need to create the textures and create a routine for mapping them to the plane, as vielzutun has done.
- Creating and projecting onto an html canvas. The advantage is that the fonts and mapping system are already available. Prisoner849 is the expert on this and can advise as to whether this would fit with the kind of application you have in mind.
There are likely other methods that I am overlooking. I have used the first two to create two-sided animated labels, but not the volume of text you have in mind.
Just voicing an “agree to disagree” objection here.