私の2dゲームエンジン用のキャンバスベースのレンダリングを書き直そうとしています。私は良い進歩を遂げており、スケーリング、ローテーション、ブレンディングで完結したwebglコンテキストにテクスチャを細かくレンダリングできます。しかし、私のパフォーマンスはうんざりです。私のテストラップトップでは、バニラの2Dキャンバスで30フレーム/秒、画面上に1,000個のエンティティを一度に取得できます。 WebGLでは、画面上に500個のエンティティを持つ30 fpsを取得します。状況が逆転すると思うよ!WebGLでバッチコールを行う最も速い方法
私は犯人がこのすべてであることを疑っている疑いがあります。Float32Array
私は投げ捨てています。ここに私のレンダリングコードは次のとおりです。
// 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;
}
より良いパフォーマンスを取得する方法上の任意のアイデア:
// 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);
},
そして、ここでは私の簡単なテストシェーダ(これらは&回転スケーリング、ブレンドが欠落している)ですか?私のdrawArraysをバッチする方法はありますか?バッファーゴミを減らす方法はありますか?
ありがとうございます!
もっと知りたい場合は、「WebGLでdrawArraysをバッチ処理する最速の方法」 –
@Mikko Doneのようにタイトルを付けることをお勧めします。ありがとう! –
@AbrahamWalters:フレームごとにエンティティごとに正確なレンダーコードを実行していますか? (別名500 * 30 = 1500回/秒)もしそうなら、タブ/ブラウザはただそこに座らせると1時間以内に(10分ではないにしても)メモリが使い果たされると思います。 –