Skip to content

TextGeometry performance #1825

Closed
Closed
@yuvadm

Description

@yuvadm

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

zz85 commented on Apr 27, 2012

@zz85
Contributor

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

yuvadm commented on Apr 27, 2012

@yuvadm
Author

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

zz85 commented on Apr 27, 2012

@zz85
Contributor

your understanding is right.

basically you can pre-calculate character geometries - eg.

cache = {}
char from a - z:
    cache[char] = text geometry (char)

now to create meshes, simply take characters needed,

textgroup = new object3d
for (char in string) : 
    char_mesh = mesh( cache[char], material )
    char_mesh.x += offset;
    textgroup.add(char_mesh);

you can try reference the generateTextGeometry(text) function in http://www.jabtunes.com/itcameupon/textEffects.js

yuvadm

yuvadm commented on Apr 27, 2012

@yuvadm
Author

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

zz85 commented on Apr 28, 2012

@zz85
Contributor

i'm not sure - that might make TextGeometry more complex than it needs to be?

yuvadm

yuvadm commented on Apr 29, 2012

@yuvadm
Author

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

zz85 commented on Apr 29, 2012

@zz85
Contributor

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

alteredq commented on Apr 30, 2012

@alteredq
Contributor

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:

object.matrixAutoUpdate = false;
object.updateMatrix();

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/

@zz85 Nice ;)

yuvadm

yuvadm commented on May 3, 2012

@yuvadm
Author

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 ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @zz85@yuvadm@alteredq

        Issue actions

          TextGeometry performance · Issue #1825 · mrdoob/three.js