【发布时间】:2017-08-30 07:54:26
【问题描述】:
我正在开发基于 Unreal 的开源 UAV 模拟 (Microsoft AirSim),我正在尝试从连接到无人机的摄像头捕获和保存图像。下面的图片展示了游戏的外观。底部最右边的视图是相机的实际视图,另外两个只是同一图像的处理版本。
现在它的设置方式是这样的:有一个相机资产,通过代码读取它作为一个捕获组件。屏幕截图中的三个视图链接到此捕获组件。当无人机在游戏中飞来飞去时,视图可以毫无问题地流式传输。但是在录制屏幕截图时,当前代码会从这个捕获组件中设置一个 TextureRenderTargetResource,然后调用 ReadPixels 并将该数据保存为图像(请参阅下面的代码流)。按原样使用 ReadPixels() 会直接阻塞游戏线程并大大降低整个游戏的速度:当我开始录制时,从 ~120 FPS 下降到不到 10 FPS。
bool saveImage() {
USceneCaptureComponent2D* capture = getCaptureComponent(camera_type, true);
FTextureRenderTargetResource* RenderResource = capture->TextureTarget->GameThread_GetRenderTargetResource();
width = capture->TextureTarget->GetSurfaceWidth();
height = capture->TextureTarget->GetSurfaceHeight();
TArray<FColor> imageColor;
imageColor.AddUninitialized(width * height);
RenderResource->ReadPixels(bmp);
}
看看this article,很明显ReadPixels()“会阻塞游戏线程,直到渲染线程赶上”。该文章包含读取像素的“非阻塞”方法的示例代码(通过删除 FlushRenderingCommands() 并使用 RenderCommandFence 标志来确定任务何时完成),但它并没有显着提高性能:速率为保存的图像略高,但游戏线程仍然以大约 20 FPS 的速度运行,因此很难控制无人机。有没有更有效的异步方法可以实现我想要做的事情,也许,比如说,在一个单独的线程中?我也有点困惑,为什么代码可以尽可能快地在屏幕上流式传输这些图像,但保存图像似乎要复杂得多。即使图像仅以 15 Hz 左右的频率保存到磁盘也可以,只要它不会过多地干扰游戏的原生 FPS。
【问题讨论】:
标签: unreal-engine4