在THREE.js中创建50000多个文本粒子

时间:2014-06-23 20:15:01

标签: javascript three.js webgl

我正在尝试创建一个包含超过50000个单字母的字符粒子系统。

找到类似的东西但用XG here写的。

创建此问题是应用程序的性能。

这里有一些简短的伪代码:

var field = new THREE.Object3D();
for (var i = 0; i < 50000; i++) {
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    context.fillText(char);
    var texture = new THREE.Texture(canvas)
    texture.needsUpdate = true;
    var spriteMaterial = new THREE.SpriteMaterial({map: texture});
    var sprite = new THREE.Sprite(spriteMaterial);
    sprite .position.set(x, y, z);
    field.add(textSprite);
}
scene.add(field);

所以现在我的问题是,是否有一些例子或某些东西,我可以看到创建这个文本数量的最佳方法?!

我还试过这个example而没有取得好成绩。

1 个答案:

答案 0 :(得分:1)

正如vals所说,你正在为每个字母创建材质和纹理。您创建画布的事实也不重要,这只是一次性开销。

您创建的每个纹理都必须占用图形内存。在纹理之后,每个渲染过程都会单独计算每个材质,因此对于50000个材质,您需要进行大量计算。

加速你所拥有的一个简单方法就是使用查找表:

var materialLUT = {};
function getMaterialForLetter(c){
    var m = materialLUT[c];
    if(m === void 0){
        //material doesn't exist, lets create it
        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');
        context.fillText(c);
        var texture = new THREE.Texture(canvas)
        texture.needsUpdate = true;
        m = materialLUT[c] = new THREE.SpriteMaterial({map: texture});
    }
    return m;
}
var field = new THREE.Object3D();
for (var i = 0; i < 50000; i++) {
    var spriteMaterial = getMaterialForLetter(char);
    var sprite = new THREE.Sprite(spriteMaterial);
    sprite.position.set(x, y, z);
    field.add(textSprite);
}
scene.add(field);

我认为应该改进的另一件事是使用PointCloud。最后 - 我认为最好使用单个纹理并通过UV获取相关字符。