从博客到博客,视频到视频,从论坛到论坛,似乎有一些不同的意见。这特别适用于canvas标签的2D上下文,而不是WebGL。我知道WebGL会给我带来更好的性能,但我的目标是了解canvas标签在2D环境中的工作原理。
我听说在#"虚拟"中预先渲染你的对象。屏幕外的画布可能是性能最好的,因为浏览器不会真正吸引它。然后人们说要使用" getImageData"从该画布中获取数据。从我的理解中返回一个base64代码,您可以将其应用于使用" putImageData"添加到DOM的画布。这不是一个巨大的性能打击吗?
我是否应该在此虚拟画布上渲染整个游戏,然后在循环内使用此方法将其放入可见的游戏中?
答案 0 :(得分:2)
是的,你可以。我建议使用requestAnimationFrame()并在游戏循环的draw()部分内,将所有单独的对象绘制到屏幕外的canavs,然后将一个get / put图像放到可见的画布上。虽然这可能会影响性能,但是当你绘制了很多对象时,这个get / put图像的开销实际上可以忽略不计。
答案 1 :(得分:2)
Canvas只是一个图像,根据我的经验,在性能方面使用画布或图像没有区别。
屏幕外或画布上没有什么不同,他们都会尽可能利用GPU。
要避免使用context.getImageData()
,context.createImageData()
和context.putImageData()
进行实时渲染,它不会利用GPU,您对其执行的任何处理都将在主内存中完成通过Javascript。虽然数据存储在类型化数组Uint8ClampedArray
中,但可以转换为任何类型的类型化数组,例如Uint32Array
允许您使用一个变量处理单个像素,而不是4。还有许多用于类型化数组的本机函数,它们提供比标准Javascript数组快得多的数组操作。
图像(包括画布作为图像)的限制因素是可用的GPU RAM量,当你超过可用的RAM量时,浏览器会根据需要将图像交换到GPU RAM中,当它这样做时与普通的RAM访问相比,GPU具有渲染能力,从主RAM到GPU RAM的传输速度很慢。当发生这种情况时,您将立即看到帧速率的损失。由于浏览器可以运行各种各样的平台而无法了解机器功能,因此在发布实时应用程序时应该小心。
如果您为高端台式机编写了具有高分辨率图像的游戏,则它在平板电脑和低端笔记本电脑上的表现不会很好。为了缓解此问题,请对图像进行下采样以匹配屏幕分辨率。在分辨率为1/8的设备上使用雇佣背景图像会给硬件带来不适当的压力。设备用于处理其屏幕的分辨率,超过此分辨率将产生重大不必要的性能损失。在这里,您可以使用屏幕外画布以设备的原始分辨率渲染图像,然后转储原始的雇佣图像。不会有质量损失,但会有很大的性能提升,将无法播放的东西变成可玩的。这适用于所有图形资源。切勿以高于您正在使用的设备的分辨率存储和使用图像。
因为你可以用画布做各种各样的事情,找出最好的东西的最好方法就是试验。监控帧速率并尝试不同的方法解决手头的问题。如果帧速率提高,你找到了更好的做事方式,如果帧速率下降,那么你使用了错误的方法。