我正在尝试创建一个包含超过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而没有取得好成绩。
答案 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获取相关字符。