Rendering text without the memory performance impact

Earlier this year I dove into Three.JS for the first time. My first small project was creating a small play at home version of The Weakest Link game seen here:https://www.youtube.com/watch?v=suu5tBtODwg. When I created this, Three.JS was only used for the ring animations and logo text. Recently, I’ve been playing more in depth with Three.JS for a few weeks now as I want to expand my developement to support more browsers for other stuff I have developed in the past.

This go round I am aiming to remake some of my older content but have ran into a snag with handling a bunch of text in Three.JS. As mentioned earlier The Weakest Link game only used text geometry for the title around the rings, everything else was done by straight HTML and embedded fonts. This go round that is not the case as all text is to be done in Three.JS. However, I’ve hit a snag…

When attempting to place textual content into the environment, the two methods I have tried so far are:

Method 1
This method utilizes the TextWrapper utility from: https://github.com/jamesaburnell/threejs-text-wrapper
Positives -This method gives me what I want as far as control over font style, size, color, wrapping etc. and also hides the text if a mesh moves in front which is exactly the behavior I want.
Negatives - This method is a SEVERE memory hog. Simple sentences just a few words long easliy up the JavaScript VM instance memory to >400 MB.

This method takes this setup of meshes (text and all):


and when it is rotated 180 degress over the x-axis it yields this:

which is the behavior I want.

The JavaScript Code

namespace.TextGroup = new TextWrapper().Wrap({
	string: "Text goes here...",
	size: 20,
	height: 0.01,
	color: 0xFFFFFF,
	lineLength: 115,
	lineHeight: 1.5,
	coords: { x: 0, y: 0, z: 0 },
	font: namespace.MyJSONFont,
	material: eval(namespace.MyMaterial),
	name: "Text"
});
			
new THREE.Box3().setFromObject( namespace.TextGroup ).getCenter( namespace.TextGroup .position ).multiplyScalar( - 1 );
			
namespace.TextGroup .position.z = 5;
			
scene.add(TextGroup);

Method 2
Positives - This method also gives me what I want as far as control over font style, size, color, wrapping etc. and it is not a memory hog (<20 MB) .
Negatives - I lose the ability to hide text behinds meshes and the text bleeds through any mesh that moves in front of it (text is always on top).

This method takes this setup of meshes and a CSS3DObject containing the text:


and when it is rotated 180 degress over the x-axis it yields this:

As you can see the text is still visible when I don’t want it to be.

The JavaScript Code

namespace.TextDiv = document.createElement("div");
namespace.TextDiv.className = "text-div";
namespace.TextDiv.innerHTML = "Text goes here...";

var textCSS3DObject = new THREE.CSS3DObject(namespace.TextDiv);

scene.add(textCSS3DObject);

I’ve tried to modify the TextWrapper utility in method 1 to merge all geometries it creates for text meshes thinking it would improve performance but this far I have not been unsuccessful. Performance still takes a huge hit and at the rate the app will cease to respond as there is a lot more text to added later on.

Is there something else I should try or that I am doing wrong that needs to be addressed here?

Just change the backface-visibility attribute of of your container <div> in CSS to
backface-visibility: hidden;

I’ve given that a shot before but it appears not to apply it and additionally if a new mesh moves in front of the text (without rotating it) it still bleeds through.

You have some of the base assumptions wrong.

CSS (DOM really) does not live in your WebGL scene, it lives outside of it, so it will not play well with the rest of your scene.

There are text examples on three.js, you could try those as a start.

Thanks for the feed back. I took another glance at the examples and found this one (don’t know how I missed it earlier): https://threejs.org/examples/?q=text#webgl_geometry_text_shapes .

I took the code for doing just the shapes part and not the lines and gave it a go. I was able to get the whole color, wrapping, hiding behind mesh, etc features I was looking for and better yet, the JavaScript VM instance memory is not pegging through the roof like before using a bunch text geometries and then trying to simplify them.

I’m going take said code and wrap it in reusable function where I can customize the material and text on the fly and start applying it as needed.

Thanks. :slight_smile:

1 Like