【发布时间】:2016-01-15 15:51:51
【问题描述】:
有一个 three.js 场景,其中包含一些 3D 对象和 200 - 300 个小文本标签(
有没有办法让精灵更快? 我阅读了有关缓存材料的信息,但标签都是唯一的 - 所以这是不可能的。
测试: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 个绘制调用。从性能的角度来看,最好将所有精灵标签一起批处理为一个批处理并通过一次调用进行绘制。
标签: performance three.js textures sprite