2 차원 게임 엔진에 대한 캔버스 기반 렌더링을 다시 작성하려고합니다. 나는 좋은 성과를 거두었고 스케일링, 회전 및 블렌딩으로 완성 된 webgl 컨텍스트에 텍스처를 잘 렌더링 할 수 있습니다. 그러나 나의 연기는 빤다. 내 테스트 랩톱에서는 바닐라 2D 캔버스에서 화면 당 1,000 개의 항목으로 한 번에 30fps를 얻을 수 있습니다. WebGL에서 화면에 500 개의 항목이있는 30fps를 얻습니다. 나는 그 상황이 역전 될 것으로 기대한다!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 분이 아닌 경우) 그냥 앉아있을 것입니다. –