我实现了一个webGL解决方案来绘制很多立方体。 我使用大缓冲区来存储顶点,偏移量,颜色并通过一次调用绘制多维数据集。 它在前10秒内以60fps运行良好。 在此之后,如果我保持标签处于活动状态,帧速率将降至30 fps并且不会升高。如果我切换到其他选项卡(没有webGL的东西)一段时间(我认为大约1分钟)并在此之后返回到我的项目,帧速率增加到60 fps并再次下降。 我认为它是GC,但如果你在代码中看到,drawScene函数不会产生数据垃圾,它只调用webGL绘制函数而不生成新数据......
我注意到Three.js和Babylon.js的这种行为。经过一段时间后,只有当我离开选项卡时,帧速率才会下降并升高。
一些想法如何解决或清理webGL状态或其他事情?
我正在使用最新的Chrome和Firefox。
var program = utils.initShaders();
utils.initAttributeLocation(program, 'position');
utils.initAttributeLocation(program, 'offset');
utils.initAttributeLocation(program, 'color');
utils.initUniformLocation(program, 'viewMat');
utils.initUniformLocation(program, 'projectionMat');
var texture = utils.getTextureFromImage('resources/noodles.jpg');
utils.resizeCanvasToDisplaySize();
var geometryDataOrg = getGeometryData(0, 0, 0); // 12 * 9 vertices
var colorDataOrg = getColorData(); // 12 * 3 colors
var geometryData = [];
var colorData = [];
var offsetData = [];
for (var x=0; x<100; x++) {
for (var z=0; z<100; z++) {
var newOffsetData = getOffsetData(x, z, 0);
for (var i=0, ilen=newOffsetData.length; i<ilen; i++) {
offsetData.push(newOffsetData[i]);
}
for (var i=0, ilen=geometryDataOrg.length; i<ilen; i++) {
geometryData.push(geometryDataOrg[i]);
}
for (var i=0, ilen=colorDataOrg.length; i<ilen; i++) {
colorData.push(colorDataOrg[i]);
}
}
}
var buffer = utils.gl.createBuffer();
utils.gl.bindBuffer(utils.gl.ARRAY_BUFFER, buffer);
utils.gl.bufferData(utils.gl.ARRAY_BUFFER, new Float32Array(geometryData), utils.gl.STATIC_DRAW);
utils.gl.enableVertexAttribArray(utils.attributes['position']);
utils.gl.vertexAttribPointer(utils.attributes['position'], 3, utils.gl.FLOAT, false, 0, 0);
var buffer1 = utils.gl.createBuffer();
utils.gl.bindBuffer(utils.gl.ARRAY_BUFFER, buffer1);
utils.gl.bufferData(utils.gl.ARRAY_BUFFER, new Float32Array(offsetData), utils.gl.STATIC_DRAW);
utils.gl.enableVertexAttribArray(utils.attributes['offset']);
utils.gl.vertexAttribPointer(utils.attributes['offset'], 3, utils.gl.FLOAT, false, 0, 0);
var buffer2 = utils.gl.createBuffer();
utils.gl.bindBuffer(utils.gl.ARRAY_BUFFER, buffer2);
utils.gl.bufferData(utils.gl.ARRAY_BUFFER, new Float32Array(colorData), utils.gl.STATIC_DRAW);
utils.gl.enableVertexAttribArray(utils.attributes['color']);
utils.gl.vertexAttribPointer(utils.attributes['color'], 1, utils.gl.FLOAT, false, 4, 0);
utils.gl.bindBuffer(utils.gl.ARRAY_BUFFER, null);
var fieldOfViewRadians = degToRad(60);
var aspect = utils.getCanvasRatio();
requestAnimationFrame(drawScene);
var projectionMatOrg = m4.identity();
projectionMatOrg = m4.perspective(fieldOfViewRadians, aspect, 1.0, 4096.0, projectionMatOrg);
utils.assignUniformValue(utils.gl.FLOAT_MAT4, 'projectionMat', projectionMatOrg);
var viewMat = [1, 0, 0, 0, 0, 6.123234262925839e-17, -1, 0, 0, 1, 6.123234262925839e-17, 0, 0, -20, -1.2246467996456087e-15, 1];
utils.assignUniformValue(utils.gl.FLOAT_MAT4, 'viewMat', viewMat);
utils.gl.bindBuffer(utils.gl.ARRAY_BUFFER, buffer);
function drawScene(time) {
utils.gl.clear(utils.gl.COLOR_BUFFER_BIT | utils.gl.DEPTH_BUFFER_BIT);
utils.gl.drawArrays(utils.gl.TRIANGLES, 0, colorData.length);
requestAnimationFrame(drawScene);
}