有没有一种廉价的方法来在每个帧的基础上从RenderTarget2D传输颜色数据?

直到最近,我们的游戏通过从场景背景纹理的一部分获取颜色数据来检查碰撞。 这个效果非常好,但随着devise的改变,我们需要检查多个纹理,并决定将这些全部渲染到一个RenderTarget2D,并检查碰撞。

public bool TouchingBlackPixel(GameObject p) { /* Calculate rectangle under the player... SourceX,SourceY: Position of top left corner of rectangle SizeX,SizeY: Aproximated (cast to int from float) size of box */ Rectangle sourceRectangle = new Rectangle(sourceX, sourceY, (int)sizeX, (int)sizeY); Color[] retrievedColor = new Color[(int)(sizeX * sizeY)]; p.tileCurrentlyOn.collisionLayer.GetData(0, sourceRectangle, retrievedColor, 0, retrievedColor.Count()); /* Check collisions */ } 

我们所面临的问题是,自从转向提供目标以来,我们正在经历FPS的大幅减less。

从我们所读到的看来,问题似乎是为了从RenderTarget2D获取数据,您需要将数据从GPU传输到CPU,而且这很慢。 这是由我们需要运行相同的function两次(每个玩家一次),不能保持相同的数据(他们可能不在同一个瓷砖上)。

我们已经尝试将GetData调用移动到tile的Draw函数并将数据存储在成员数组中,但是这似乎并没有解决问题(因为我们仍然非常有规律地在一个tile上调用GetData – 每更新一次每一次抽奖)。

任何你可以给我们的帮助都是很大的,因为这个碰撞系统给我们的力量是相当不可思议的,但是提供目标的开销会使它不可能保持。

简单的答案是: 不要这样做

这听起来像是将你的碰撞数据的合成卸载到GPU上是一种性能优化,但是没有奏效 – 所以正确的行动方式是恢复这个改变。

你应该简单地在CPU上进行碰撞检查。 而且我会进一步提出,多次运行碰撞算法并通过合并结果来确定碰撞响应的速度可能会更快,而不是将整个场景合成到单个图层上并运行一次碰撞检测。

如果您在执行碰撞之前使用渲染目标来支持转换,则情况尤其如此。

(对于简单的二维像素碰撞检测,请参阅此示例 。如果您需要支持转换,请参阅此示例 。)

我想,你的瓷砖的碰撞层不会改变。 或者至少变化不是很频繁。 因此,您可以将每个拼贴的颜色存储在数组或其他结构中。 这将减少从GPU传输到CPU的数据量,但要求RAM中存储的附加数据不会太大。