Ich versuche, meine Canvas-basierte Rendering für meine 2d Game Engine neu zu schreiben. Ich habe gute Fortschritte gemacht und kann Texturen in den Webgl-Kontext übertragen, komplett mit Skalierung, Drehung und Überblendung. Aber meine Leistung ist schlecht. Auf meinem Test-Laptop kann ich 30 fps in Vanille 2d Leinwand mit 1.000 Einheiten auf dem Bildschirm auf einmal bekommen; In WebGL bekomme ich 30 fps mit 500 Entitäten auf dem Bildschirm. Ich würde erwarten, dass die Situation umgekehrt ist!Der schnellste Weg zu Batchaufrufen in WebGL
Ich habe einen schleichenden Verdacht, dass der Schuldige ist all dies Float32Array
Puffer Müll Ich bin herumwerfen. Hier ist mein Render-Code:
// 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);
},
Und hier ist meine einfachen Test-Shadern (diese Mischung fehlt, Skalierung & Rotation):
// 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;
}
Alle Ideen, wie eine bessere Leistung zu bekommen? Gibt es eine Möglichkeit, meine drawArrays zu chargen? Gibt es eine Möglichkeit, den Puffermüll zu reduzieren?
Danke!
Um interessanter zu werden, schlage ich vor, dass Sie Ihre Frage wie "Der schnellste Weg, Batch-DrawArrays auf WebGL" –
@Mikko Done. Vielen Dank! –
@AbrahamWalters: Führen Sie diesen genauen Render-Code für jede Entität für jeden Frame aus? (aka 500 * 30 = 1500 mal pro Sekunde) Wenn das der Fall ist, denke ich, dass dem Tab/Browser innerhalb einer Stunde (wenn nicht zehn Minuten) der Speicher ausgehen wird, wenn Sie es einfach dort sitzen lassen. –