我正在開發一個基於虛幻的開源無人機模擬(Microsoft AirSim),我嘗試捕獲並保存附加到無人機。下面的圖像給出了遊戲外觀的一個概念。底部的最右側視圖是相機的實際視圖,另外兩個視圖僅是同一圖像的處理版本。虛幻引擎:在沒有阻塞遊戲線程的情況下訪問/保存遊戲中的圖像到磁盤
現在它的成立這樣的方式:有一個攝像頭的資產,這是通過代碼捕獲組分閱讀。截圖中的三個視圖鏈接到此捕獲組件。隨着無人機在遊戲中飛行,觀看信息流沒有任何問題。但是在錄製屏幕截圖時,當前代碼從該捕獲組件創建一個TextureRenderTargetResource,隨後調用ReadPixels並將該數據保存爲圖像(請參閱下面的代碼流)。直接使用ReadPixels()會直接阻塞遊戲線程,並會大幅減慢整個遊戲速度:當我開始記錄時,從大約120 FPS下降到低於10 FPS。在this article
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);
}
來看,似乎顯而易見,ReadPixels()「將阻塞遊戲線程,直到渲染線程已經趕上了」。該文章包含讀取像素的「非阻塞」方法的示例代碼(通過去除FlushRenderingCommands()並使用RenderCommandFence標誌來確定任務何時完成),但它不會顯着提高性能:哪些圖像保存稍高,但遊戲線程仍然以大約20 FPS的速度運行,因此很難控制無人機。有沒有更有效的異步方法可以實現我想要做的事情,也許可以說,在一個單獨的線程中?我也有點困惑,爲什麼代碼在屏幕上儘可能快地傳輸這些圖像沒有問題,但保存圖像似乎更復雜。即使圖像只保存在15赫茲左右的磁盤上也沒問題,只要它不會太多幹擾遊戲原生FPS。
您能解釋一下更多關於您的意思嗎?「看看從無人機攝像頭截圖而不是操縱像素數據?」因爲我知道的唯一方法可以通過ReadPixels()命令將捕獲的圖像數據提取出來。而現在,它正在寫壓縮的PNG文件。如果我將它們存儲在TArray中,我猜你建議我在單獨的線程中執行它? – HighVoltage
我剛剛添加了另一個想法,我的帖子:)你可以調用一個控制檯命令從玩家相機截圖。也許你可以找到該命令的來源,然後發現如何給它一個不同的源攝像頭。截圖命令保存了一個文件,targa我認爲。道歉,渲染不是我的專業領域。這裏的問題在於,您錄製的視頻不僅僅是拍攝單個圖像。也許看看添加第三方媒體庫? – JonS
我也認爲在遊戲結束後保存圖像不會導致fps下降,如果這是你想要的,btw會嘗試使用虛幻的捕捉功能https://docs.unrealengine.com/latest/INT/引擎/基礎/屏幕截圖/,它也保存圖片本身,並且會比你現在正在做的更快。 – LumbusterTick