我正在开发一个基于虚幻引擎的开源无人机模拟器(Microsoft AirSim),尝试从连接到无人机的摄像头中捕获并保存图像。下面的图片展示了游戏的外观,底部最右边的视图是来自摄像头的实际视图,其他两个是相同图像的处理版本。
目前的设置如下:有一个相机资源,通过代码作为捕获组件进行读取。屏幕截图中的三个视图与此捕获组件相关联。在游戏中飞行无人机时,这些视图可以流畅地传输。但是,在记录屏幕截图方面,当前的代码从此捕获组件设置了TextureRenderTargetResource,并随后调用ReadPixels将数据保存为图像(请参见下面的代码流程)。直接使用ReadPixels()会阻塞游戏线程并严重降低整个游戏的速度:当我开始录制时,帧率从约120 FPS降至不到10 FPS。
看起来this article,ReadPixels()函数“会阻塞游戏线程直到渲染线程追上”。文章提供了一个“非阻塞”读取像素的示例代码(通过删除FlushRenderingCommands()并使用RenderCommandFence标志确定任务何时完成),但它并没有显著改善性能:保存图像的速率略有提高,但游戏线程仍然只运行约20 FPS,因此很难控制UAV。是否有更有效的异步方法可以实现我想要做的事情,也许在单独的线程中?我还有点困惑为什么代码在屏幕上流式传输这些图像速度非常快,但保存图像似乎更加复杂。即使图像以每秒15帧的速度保存到磁盘上,只要不过多干扰游戏的本机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,因此很难控制UAV。是否有更有效的异步方法可以实现我想要做的事情,也许在单独的线程中?我还有点困惑为什么代码在屏幕上流式传输这些图像速度非常快,但保存图像似乎更加复杂。即使图像以每秒15帧的速度保存到磁盘上,只要不过多干扰游戏的本机FPS,这也是可以接受的。