Description
I'm working on a scene that heavily involves lots of 3D TextGeometry
objects. Ideally, I need to have several hundred objects on the scene. Each text object is roughly one sentence with several words. Each object is positioned and rotated differently.
Unfortunately, even with the most basic scene (no shaders, no sophisticated rendering), I'm having trouble adding several dozen objects. The scene takes a lot of time to load in the good case, and once I try adding more than ~100 text objects, the scene simply takes forever to load.
Simple initialization:
renderer = new THREE.WebGLRenderer();
renderer.setSize(WIDTH, HEIGHT);
document.body.appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 40, WIDTH / HEIGHT, 2, 4000 );
camera.position.set( -1200, 800, 1200 );
scene.add(camera);
controls = new THREE.FirstPersonControls(camera);
controls.movementSpeed = 250;
controls.lookSpeed = 0.05;
light = new THREE.PointLight(0xffff00);
light.position.set(10, 0, 10);
scene.add(light);
Iteration over text:
$.each(t, function (_i, texts) { // several dozen to several hundreds
//console.log(t);
var text3d = new THREE.TextGeometry('Lorem ipsum dolor sit amet, consectetur adipiscing elit.', {
size: 16,
height: 2,
//curveSegments: 2,
font: "helvetiker",
bend: true,
});
var textMaterial = new THREE.MeshBasicMaterial({
color : 0x111111,
overdraw : true
});
// text3d.computeBoundingBox();
// text3d.computeVertexNormals();
var text = new THREE.Mesh(text3d, textMaterial);
text.position.x = t.someXpos;
text.position.y = t.someYpos;
text.position.z = t.someZpos;
text.rotation.y = t.someYrot;
text.rotation.z = t.someZrot;
scene.add(text);
});
I don't know if it's related to the bad performance or not, but for each object I'm also getting a cannot triangulate polygon
warning in the console.
Any ideas what I might be doing wrong? Ideas on how I can streamline the initial text rendering? Once the text is added to the scene it won't really change.
Any tips on how to improve TextGeometry
performance would be very helpful. Thanks!
Activity
zz85 commentedon Apr 27, 2012
Text geometries mesh generations are a little costly, since there's shapes triangulations etc.
Try caching individual character meshes, so it does not need to computed unnecessary.
I used this approach in http://www.jabtunes.com/itcameupon/ so the 3d text generation seems to be done in almost realtime.
I had a brief write up on this in section 8 of http://www.lab4games.net/zz85/blog/2012/03/01/experiments-behind-it-came-upon/ too.
yuvadm commentedon Apr 27, 2012
So if I understand correctly, I need to generate a
TextGeometry
for each char in my alphabet, and reuse it to build each sentence?Can you post some simple (pseudo) code so I can grasp what you're suggesting? It'd help me a lot. Thanks!
zz85 commentedon Apr 27, 2012
your understanding is right.
basically you can pre-calculate character geometries - eg.
now to create meshes, simply take characters needed,
you can try reference the
generateTextGeometry(text)
function in http://www.jabtunes.com/itcameupon/textEffects.jsyuvadm commentedon Apr 27, 2012
Thanks for the tip, I'm working on the implementation right now.
Is there any reason this sort of caching shouldn't be implemented within
TextGeometry
?zz85 commentedon Apr 28, 2012
i'm not sure - that might make
TextGeometry
more complex than it needs to be?yuvadm commentedon Apr 29, 2012
OK, so after implementing separate char
TextGeometry
caching, I indeed get much better initialization times, but now the framerate has dropped considerably.Any idea what I can improve?
zz85 commentedon Apr 29, 2012
hmm... you can try using
THREE.GeometryUtils.merge()
although all there's always some trade offs. Try tweaking your text geometries parameters - the number of segments and divisions can affect the total number of faces and performance easily.and you could consider looking at my freshly baked mesh up of having a million crisp text characters in webgl. http://jabtunes.com/labs/3d/million_letters_zoom/
alteredq commentedon Apr 30, 2012
If runtime was fast before with single geometry per sentence and it's now slow with single geometry per letter, your bottleneck may be scene graph.
If you don't need to move your text, you can try to turn off matrix updates for individual letter objects:
@zz85 Nice ;)
yuvadm commentedon May 3, 2012
Thanks everyone for the great advice. Indeed it's a game of tradeoffs. There is no magic solution.
I used all this advice to hack something that works pretty much like I need.
Oh, and I threw some more hardware at the problem ;)