具有位图区域采样效果的Chrome性能问题(JavaScript)

时间:2016-12-27 17:57:38

标签: javascript google-chrome bitmap bitmapdata

我正在使用引擎Phaser编写HTML5游戏,其中我正在实现基本上是活动背景,背景响应游戏对象的移动。我正在使用的第一个是水波纹效果,它使用bitmapData对象上的区域采样。我以为我的代码中存在性能问题,但事实证明Firefox像梦一样运行它。当我的游戏对象太靠近屏幕的顶部或底部时,Chrome开始时运行速度稍慢,速度慢于10 FPS。 (我为什么会有所作为而感到茫然。)

This thread表示Chrome的图像处理性能较差,建议将较大的图像数据分成较小的部分。我不知道在我的情况下这是否可行,因为这不仅仅是在屏幕上显示的图像,而是基于彼此相邻的像素的效果,刷新每个帧。即使有可能,我认为Chrome最终还是要完成相同数量的工作或更多工作,以使四个单独的位图相互交互,就像它们是一个一样。

我已经在Chrome中进行了几个小时的性能测试,问题肯定在于它通过读取源imageData中的像素并将它们写入另一个位置来实际创建效果的方法。目标imageData(下面的ws.displace(x,y)方法)。

function waterStage(canvas) {

    var ws = new Object();
    ws.dampFactor = 16;
    ws.magFactor = 150;
    ws.dispFactor = 0.5;
    ws.lumFactor = 1;

    ws.width = canvas.width;
    ws.height = canvas.height;

    // Initialize height data caches
    ws.pMaps = [];
    var map1 = new Array(ws.width+2);
    var map2 = new Array(ws.width+2);

    for (x=0; x < map1.length; x++) {
        map1[x] = new Array(ws.height+2);
        map2[x] = new Array(ws.height+2);
    }

    for (x=0; x < map1.length; x++) {
        for (y=0; y < map1[x].length; y++) {
            map1[x][y] = 0;
            map2[x][y] = 0;
        }
    }

    ws.pMaps.push(map1, map2);

    ws.stageInit = function(canvas) {
        canvas.fill(100,100,100);
        canvas.ctx.strokeStyle = "#000000";
        canvas.ctx.lineWidth = 2;
        canvas.ctx.moveTo(0,0);
        for (y=0; y < ws.height; y+=10) {
            canvas.ctx.beginPath();
            canvas.ctx.moveTo(0,y);
            canvas.ctx.lineTo(ws.width,y);
            canvas.ctx.closePath();
            canvas.ctx.stroke();
        }

        ws.sourceData = canvas.ctx.getImageData(0, 0, ws.width, ws.height);
        ws.targetData = canvas.ctx.getImageData(0, 0, ws.width, ws.height);
    }

    ws.setWave = function(pnt) {
        ws.pMaps[0][pnt.x-1][pnt.y-1] = ws.magFactor//*pnt.magnitude;
    }

    ws.resolveWaves = function(x,y) {
        // Calculate the net result of the wave heights
        ws.pMaps[1][x][y] = ((ws.pMaps[0][x-1][y]+ws.pMaps[0][x+1][y]+ws.pMaps[0][x][y-1]+ws.pMaps[0][x][y+1]) / 2)
                            -ws.pMaps[1][x][y];
        ws.pMaps[1][x][y] -= (ws.pMaps[1][x][y]/ws.dampFactor);
    }

    ws.displace = function(x,y) {

        var displace = Math.floor(ws.pMaps[1][x][y]*ws.dispFactor);
        var xCorrect = x-1, yCorrect = y-1;
        var targetIndex = (xCorrect + yCorrect * ws.width)*4;

        if (displace == 0) {
            ws.targetData.data[targetIndex] = ws.sourceData.data[targetIndex];
            ws.targetData.data[targetIndex+1] = ws.sourceData.data[targetIndex+1];
            ws.targetData.data[targetIndex+2] = ws.sourceData.data[targetIndex+2];
        }

        else {

            if (displace < 0) {
                displace += 1;
            }

            var sourceX = displace+xCorrect;
            var sourceY = displace+yCorrect;
            var sourceIndex = (sourceX + sourceY * ws.width)*4;

            //var lum = ws.pMaps[1][x][y]*ws.lumFactor;

            ws.targetData.data[targetIndex] = ws.sourceData.data[sourceIndex];//+lum;
            ws.targetData.data[targetIndex+1] = ws.sourceData.data[sourceIndex+1];//+lum;
            ws.targetData.data[targetIndex+2] = ws.sourceData.data[sourceIndex+2];//+lum;

        }
    }

    ws.stageRefresh = function(moves, canvas) {
        canvas.clear();

        for (j=0; j < moves.length; j++) {
            ws.setWave(moves[j]);
        }

        for (x=1; x <= ws.width; x++) {
            if (ws.pMaps[1][x][0] != 0 || ws.pMaps[0][x][0] != 0) {
                alert("TOP ROW ANOMALY");
            }
            for (y=1; y <= ws.height; y++) {
                ws.resolveWaves(x,y);
                ws.displace(x,y);
            }
        }

        ws.pMaps.sort(function(a,b) { return 1 });
        //ws.pMaps[0] = ws.pMaps[1];
        //ws.pMaps[1] = temp;

        canvas.ctx.putImageData(ws.targetData, 0, 0);
    }

    return ws;
}

canvas是作为背景纹理给出的bitmapData(不是HTML5画布;对不起,如果这令人困惑)。每次更新帧都会调用ws.stageRefresh(moves,canvas)

在我尝试将拆分为四位图解决方案之前,有没有人有其他方法可以提高Chrome效果?

0 个答案:

没有答案