Sto tentando di riscrivere il rendering basato su canvas per il mio motore di gioco 2D. Ho fatto buoni progressi e posso rendere tridimensionali le trame sul contesto webgl, complete di ridimensionamento, rotazione e fusione. Ma la mia prestazione fa schifo. Sul mio portatile di prova, posso ottenere 30 fps in canvas vanilla 2d con 1.000 entità sullo schermo contemporaneamente; in WebGL, ottengo 30 fps con 500 entità sullo schermo. Mi aspetterei che la situazione fosse invertita!Il modo più veloce per le chiamate batch in WebGL
Ho un vago sospetto che il colpevole sia tutto questo immondizia Float32Array
nel buffer che mi sto lanciando. Ecco il mio codice di rendering:
// boilerplate code and obj coordinates
// grab gl context
var canvas = sys.canvas;
var gl = sys.webgl;
var program = sys.glProgram;
// width and height
var scale = sys.scale;
var tileWidthScaled = Math.floor(tileWidth * scale);
var tileHeightScaled = Math.floor(tileHeight * scale);
var normalizedWidth = tileWidthScaled/this.width;
var normalizedHeight = tileHeightScaled/this.height;
var worldX = targetX * scale;
var worldY = targetY * scale;
this.bindGLBuffer(gl, this.vertexBuffer, sys.glWorldLocation);
this.bufferGLRectangle(gl, worldX, worldY, tileWidthScaled, tileHeightScaled);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this.texture);
var frameX = (Math.floor(tile * tileWidth) % this.width) * scale;
var frameY = (Math.floor(tile * tileWidth/this.width) * tileHeight) * scale;
// fragment (texture) shader
this.bindGLBuffer(gl, this.textureBuffer, sys.glTextureLocation);
this.bufferGLRectangle(gl, frameX, frameY, normalizedWidth, normalizedHeight);
gl.drawArrays(gl.TRIANGLES, 0, 6);
bufferGLRectangle: function (gl, x, y, width, height) {
var left = x;
var right = left + width;
var top = y;
var bottom = top + height;
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
left, top,
right, top,
left, bottom,
left, bottom,
right, top,
right, bottom
]), gl.STATIC_DRAW);
},
bindGLBuffer: function (gl, buffer, location) {
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.vertexAttribPointer(location, 2, gl.FLOAT, false, 0, 0);
},
Ed ecco i miei semplici shader di test (questi mancano miscelazione, ridimensionamento & rotazione):
// fragment (texture) shader
precision mediump float;
uniform sampler2D image;
varying vec2 texturePosition;
void main() {
gl_FragColor = texture2D(image, texturePosition);
}
// vertex shader
attribute vec2 worldPosition;
attribute vec2 vertexPosition;
uniform vec2 canvasResolution;
varying vec2 texturePosition;
void main() {
vec2 zeroToOne = worldPosition/canvasResolution;
vec2 zeroToTwo = zeroToOne * 2.0;
vec2 clipSpace = zeroToTwo - 1.0;
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
texturePosition = vertexPosition;
}
Tutte le idee su come ottenere prestazioni migliori? C'è un modo per raggruppare i miei DrawArray? C'è un modo per ridurre la spazzatura del buffer?
Grazie!
Per attrarre più intestati ti suggerisco di intitolare la tua domanda come "Il modo più veloce per estrarre batchArray su WebGL" –
@Mikko Fatto. Grazie! –
@AbrahamWalters: stai eseguendo l'esatto codice di rendering per ogni entità per ogni frame? (alias 500 * 30 = 1500 volte al secondo) Se è così, penso che la scheda/browser esaurirà la memoria entro un'ora (se non dieci minuti) se la lasci semplicemente seduta lì. –