如何解决在HTML5 canvas中快速操纵drawImage亮度
我已经制作了一个基于图块的游戏,并且正在使用2D画布上下文来渲染图块。仅渲染视图中的图块,一次渲染约800个。每个图块为10x10像素,延伸至40x40。我需要单独控制每个图块的亮度。无需调整图块的亮度,即使在移动浏览器上,它也可以保持60 fps不变。
我尝试更改图块亮度的第一种方法是使用ctx.filter
属性,例如ctx.filter = 'brightness(<brightnessValue>)';
,但这确实很慢,并且提供了大约10 fps。
然后我尝试将图像绘制到另一个较小的画布上,获取图像数据,将RGB值乘以<brightnessValue>
,然后将该图像数据放到主画布上。这种方法有效,但效果略好一些,达到约14 fps,仍然无法使用。
我尝试的最后一种方法是在每个图块上绘制一个半透明的正方形,但是性能仍然很差,当所有图块都在屏幕上时约为30 fps。方块之间也有1 px的间隙,当我尝试将方块的大小增加一个像素时,由于透明度和混合,重叠部分会产生相似的线条。
这是我编写的最新功能来绘制图块:
function renderImage(assetID,width,height,posX,posY,rotation,brightness) {
let x = w / 2 - (cameraX - posX); // calculate the x position to draw the image on the display
let y = h / 2 + (cameraY - posY); // calculate the y position to draw the image on the display
if (x > -width && x < w + width && y > -height && y < h + height) {
let image = getEntityImage(assetID);
rotation *= 0.01745329; // // convert degrees to radians
ctx.translate(x,y);
ctx.rotate(rotation);
ctx.drawImage(image,image.width,image.height,-width / 2,-height / 2,height); // draw the image
if (brightness && brightness != 1) {
ctx.fillStyle = 'rgba(' + (brightness > 1 ? '255,255,' : '0,') + Math.abs(1 - brightness);
ctx.fillRect(-width/2-1,-width/2-1,width+2,width+2); // draw the image
}
ctx.rotate(-rotation); // reset rotation
ctx.translate(-x,-y); // reset translation
}
}
这是调用上述函数的代码:
for (let y = ylimN; y <= ylimP; y++) {
for (let x = xlimN; x <= xlimP; x++) {
let xp = x * 40;
let yp = y * 40;
let blockVal = map[x + y * mapWidth]; // get the value of the block: (0 for air,1 for grass etc.)
if (blockVal > 0) renderImage(blockVal,40,xp,yp,brightnessValue);
}
}
有哪些选项可以更改使用drawImage()绘制的图像的亮度,该图像的速度至少为60 fps?还是我应该只使用WebGL重做所有渲染,这会很痛苦吗?
编辑:在进一步测试了矩形覆盖方法之后,似乎矩形覆盖在图块上的性能下降只是Chrome(在所有平台上)的问题。在Firefox上,它可以保持恒定的60 fps,并且没有因反锯齿而造成的差距。 iOS Safari,macOS Safari和Android上的Firefox也是如此。我确实确实需要在Chrome上使用它,所以我认为最好的选择是使用WebGL。
我了解了有关WebGL,顶点着色器和片段着色器的更多信息,并使用它们进行了一些项目,而且我发现做我想做的事情并不像最初想的那样具有挑战性,并且它将还可以让我通过稍微高级些的着色器在块上创建平滑的照明和其他效果,因此,除了性能以外,它肯定还有其他好处。因此,我已经开始对其进行更改以使用WebGL。为GPU编写代码非常有趣。
对于感兴趣的人,我将发布指向原始代码以及完成后实现的WebGL代码的链接。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。