在我的情况下,我想在地形上放置一些带有某些城市名称的标签。但是当我放十个以上时,fps会下降很多。
我已按照此处编写的代码http://stemkoski.github.io/Three.js/Sprite-Text-Labels.html
我的代码是这样的:
var canvas = document.createElement('canvas');
var sizeCanvas = 250;
canvas.width = sizeCanvas;
canvas.height = sizeCanvas;
var context = canvas.getContext('2d');
context.font = "Bold " + size + "px " + font;
context.textAlign = 'center';
contexto.fillStyle = "rgba(10, 10, 10, 1.0)";
contexto.fillText(text, sizeCanvas / 2, sizeCanvas / 2);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
var labelMaterial = new THREE.SpriteMaterial(
{map: texture, useScreenCoordinates: false});
var label = new THREE.Sprite(labelMaterial);
label.position.x = this._vector.x;
label.position.y = this._vector.y;
label.position.z = this._vector.z;
etiqueta.scale.set(10, 10, 1.0);
scene.add(label);
我认为合并精灵的主要麻烦在于每个标签的不同纹理。
感谢您的建议!
答案 0 :(得分:2)
为了获得最终的性能提升(比@raphaelRauwolf所建议的更多的工作,在这里谈论数十万)你必须使用ParticleSystem(使用GL_POINT渲染)和使用子映像动态分配的TextureAtlas({{3}根据相机的最近邻居(https://github.com/mrdoob/three.js/pull/4661)。对于不在相机周围的其他名牌,您可以使用第二个带有较小预览铭牌的TextureAtlas。
如果你只有大约1&000;你可以做同样的事情,没有最近的邻居和子成像。只需使用所有铭牌创建TextureAtlas并使用THREE.ParticleSystem渲染它们:)
如果你对这两种方法中的一种感兴趣,请告诉我,我会详细说明。
答案 1 :(得分:1)
基本上,您为每个标签创建一个画布对象。你可以做的是,你将Base64编码的图像从画布传递给纹理,并将下一个标签写入同一个画布。这应该会给你带来性能提升。例如:
// create the canvas once
var canvas = document.createElement('canvas');
// set the size of the canvas
var sizeCanvas = 250;
canvas.width = sizeCanvas;
canvas.height = sizeCanvas;
// get the context and set the styles
var context = canvas.getContext('2d');
context.font = "Bold " + size + "px " + font;
context.textAlign = 'center';
context.fillStyle = "rgba(10, 10, 10, 1.0)";
// iterate through your labels
for(var i = 0, j = myLabels.length; i < j; i++){
contex.fillText(myLabels[i].text, sizeCanvas / 2, sizeCanvas / 2);
// create the texture
var texture = new THREE.Texture(canvas.toDataURL());
texture.needsUpdate = true; // don't know if this is needed
// put the texture into the material
var labelMaterial = new THREE.SpriteMaterial({map: texture, useScreenCoordinates: false});
var label = new THREE.Sprite(labelMaterial);
// set the label position to the vector, maybe you should put the vector into myLabels aswell
label.position = this._vector.clone();
// add the label to the scene
scene.add(label);
// clear the canvas for the new text
context.clearRect(0,0,sizeCanvas,sizeCanvas);
}
etiqueta.scale.set(10, 10, 1.0);