有啥方法可以在不使用 getImageData() 的情况下在 JavaScript 中找到像素的颜色?

Posted

技术标签:

【中文标题】有啥方法可以在不使用 getImageData() 的情况下在 JavaScript 中找到像素的颜色?【英文标题】:Is there any way to find the color of a pixel in JavaScript WITHOUT using getImageData()?有什么方法可以在不使用 getImageData() 的情况下在 JavaScript 中找到像素的颜色? 【发布时间】:2022-01-08 16:02:30 【问题描述】:

我正在使用 javascript 和原生 Canvas API (WebGL) 制作一款小型在线多人游戏。我想在屏幕上找到像素的颜色作为碰撞检测的一种形式,我认为它可以节省资源,不必每帧处理每个形状,而是简单地检查某个像素的颜色是否在某个位置是这样的,它正在接触一个形状。 (我希望这是有道理的)

我进行了一些测试,在没有碰撞检测的情况下,平均帧延迟约为 4-5 毫秒,然后当我对画布上下文的 .getImageData() 方法进行一次调用时,帧延迟突然上升到 19- 20 毫秒...

据我所知,getImageData() 是检查给定像素颜色的唯一方法,但我不得不认为还有其他方法不会引入如此大的延迟。

我尝试在屏幕的一小部分而不是较大部分上运行 getImageData(),并且 1x1 像素请求引入了 10 毫秒延迟,其中 600x600 像素请求大约为 15 毫秒...所以问题不在于数量/大小请求,而只是请求本身非常慢,所以这里没有优化的潜力,我需要另一种方式。

此外,缓存图像数据也不是一种选择。我需要在每一帧都轮询这些像素,我无法缓存它(因为播放器和它需要碰撞的对象都在不断移动,并且它们被互联网控制,所以也无法预测在哪里他们会在任何给定时间......我需要轮询每一帧,没有例外)

要清楚,我不是在问如何编写碰撞或如何制作像素完美的碰撞检测系统......我只是在问如何在画布上获取像素的颜色而不必使用 @ 987654324@ 因为.toImageData() 对于我的用例来说太慢了。

【问题讨论】:

你的前提是错误的:检查像素的颜色会比你能想到的最坏的碰撞检测要慢。您还说您正在使用 webgl 上下文,但这没有 getImageData 方法,只有 2d 上下文。 @Kaiido 哦,那我的错。我的印象是 2D 上下文只是 WebGL 之上的一层?它仍然使用 WebGL,不是吗?此外,您如何确定检查像素颜色会比碰撞检测慢?在我的用例中,我在屏幕上有大约 200 条弧线/线(每秒添加大约 5-6 次新弧线)......你真的认为每帧检查数千条弧线的碰撞会比获取更快吗?单个像素的颜色? 不,它不在 WebGL 之上。 2D 上下文可能是硬件加速的,因此可以像 WebGL 一样使用 GPU,但这些仍然是完全独立的 API。是的,我确信它会更慢,正是因为 2D 上下文可能是硬件加速的。要读取像素数据,浏览器必须使上下文减速并将缓冲区从 GPU 移动到 CPU。这不仅在完成时很慢,甚至会减慢所有后续绘图操作。另一方面,计算交集只是算术,现代 CPU 可以毫无问题地完成。 谢谢!这仍然不能回答我的问题,但它是有用的信息,它可以帮助指导我找到解决方案。 【参考方案1】:

标准碰撞检测可能最终成为更好的选择。像素完美检查适用于复杂物体的完美碰撞检测,但如果像素很多,成本会很高。

我可能会推荐使用简单形状的标准碰撞检测。如果处理得当,它应该具有良好的性能,即使对于更复杂的游戏也是如此。

如果您确实想使用像素完美碰撞,您需要先检查两个对象的矩形边界框,以确保它们彼此不远。如果它们的边界框相交,则可以使用精灵的位掩码快速检查每个像素是否重叠。 This question has a bit more info. It's not JS, but the concept would be the same.

【讨论】:

感谢您的回答,但这不是有用的信息。我不是要求用不同的方式来编写我的碰撞检测,也不是在问如何进行像素完美的碰撞......我是在问如何在不使用.getImageData() 的情况下获得像素的颜色,而你的答案没有甚至不要碰那个。

以上是关于有啥方法可以在不使用 getImageData() 的情况下在 JavaScript 中找到像素的颜色?的主要内容,如果未能解决你的问题,请参考以下文章

有啥方法可以在不使用 XMPP 协议的情况下连接到 Facebook 聊天服务?

有啥方法可以在不使用 IDFA 的情况下为设备生成唯一 ID? [复制]

有啥方法可以在不使用文件的情况下将 MIDI 加载到 AKAppleSequencer 或 AKSequencer 中?

有啥方法可以在不使用自适应付款的情况下为第三方处理付款?

有啥方法可以在不使用访问令牌/客户端 ID 的情况下获取特定主题标签的 Instagram 图像?

Laravel:有啥方法可以在不编译的情况下加载刀片模板?