2014-05-23 70 views
0

就我而言,我想在地形上加上一些城市名稱的標籤。但是當我放置超過10個時,fps會減少很多。有沒有什麼辦法可以將Sprites合併爲Three.js中的幾何?

我跟着這裏寫的代碼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); 

我supose是合併精靈的主要問題是對diferent紋理每個標籤。

感謝您的建議!

+1

你想讓你的城市標籤始終面對相機嗎? – gaitat

+0

@gaitat確實如此。 – alexGrac

+0

然後,你不能真正將所有的精靈合併爲一個。一個大精靈面對鏡頭的方式不同於單獨的小精靈。 – gaitat

回答

0

基本上你會爲每個標籤創建一個畫布對象。你可以做的是,你將畫布上的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); 
2

對於最終的性能提升(更多的工作比@raphaelRauwolf建議,這裏說hundredthousands),你不得不用TextureAtlas你subimaging動態分配一起使用粒子系統(帶GL_POINT渲染) (https://github.com/mrdoob/three.js/pull/4661)根據相機的最近鄰居(http://threejs.org/examples/#webgl_nearestneighbour)。對於不在相機周圍的其他銘牌,可以使用第二個具有較小預覽銘牌的TextureAtlas。

如果你只有1'000左右,你可以做同樣的沒有最近鄰和subimaging。只需使用所有銘牌創建TextureAtlas並使用THREE.ParticleSystem渲染它們即可:)

如果您對這兩種方法中的一種感興趣,請告訴我,我會詳細說明。

相關問題