有一个three.js所场面与一些3D对象和200 - 300小的文本标签(< 10%是相机可见的一个观点)。添加文本精灵将FPS从60降低到30 - 40,并且它也非常耗费内存。three.js所 - 雪碧/文本标签性能
有没有办法让sprite更快? 我读过缓存材料,但标签都是唯一的 - 所以这是不可能的。
测试:https://jsfiddle.net/h9sub275/4/ (你可以改变SPRITE_COUNT看到你的计算机上的FPS下降)
编辑1:画布大小设置为文本边界将减少内存消耗,但不能提高FPS。
var Test = {
SPRITE_COUNT : 700,
init : function() {
this.renderer = new THREE.WebGLRenderer({antialias : true}); // false, a bit faster without antialias
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.container = document.getElementById('display');
this.container.appendChild(this.renderer.domElement);
this.camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 1000);
this.scene = new THREE.Scene();
this.group = new THREE.Object3D();
this.scene.add(this.group);
for (var i = 0; i < this.SPRITE_COUNT; i++) {
var sprite = this.makeTextSprite('label ' + i, 24);
sprite.position.set(Math.random() * 20 - 10, Math.random() * 20 - 10, Math.random() * 20 - 10);
this.group.add(sprite);
}
this.stats = new Stats();
this.stats.domElement.style.position = 'absolute';
this.stats.domElement.style.left = '0px';
this.stats.domElement.style.top = '0px';
document.body.appendChild(this.stats.domElement);
this.render();
},
render : function() {
var self = this;
this.camera.rotation.x += 0.002;
this.renderer.render(this.scene, this.camera);
this.stats.update();
requestAnimationFrame(function() {self.render();});
},
makeTextSprite : function(message, fontsize) {
var ctx, texture, sprite, spriteMaterial,
canvas = document.createElement('canvas');
ctx = canvas.getContext('2d');
ctx.font = fontsize + "px Arial";
// setting canvas width/height before ctx draw, else canvas is empty
canvas.width = ctx.measureText(message).width;
canvas.height = fontsize * 2; // fontsize * 1.5
// after setting the canvas width/height we have to re-set font to apply!?! looks like ctx reset
ctx.font = fontsize + "px Arial";
ctx.fillStyle = "rgba(255,0,0,1)";
ctx.fillText(message, 0, fontsize);
texture = new THREE.Texture(canvas);
texture.minFilter = THREE.LinearFilter; // NearestFilter;
texture.needsUpdate = true;
spriteMaterial = new THREE.SpriteMaterial({map : texture});
sprite = new THREE.Sprite(spriteMaterial);
return sprite;
}
};
window.onload = function() {Test.init();};
如果我不得不冒险猜测,我会说three.js是做每个精灵标签1 drawcall。从性能角度来看,最好将所有精灵标签一起批量打包成一个批次并用一次调用进行绘制。 –