ピクセルデータにアクセスし、ゲーム内のカメラからディスクに画像を保存しようとしています。最初は、レンダリングターゲットとその後のRenderTarget-> ReadPixels()を使用するのが簡単でしたが、ReadPixels()のネイティブ実装ではFlushRenderingCommands()の呼び出しが含まれていたため、画像が保存されるまでゲームスレッドがブロックされていました。計算集中的な操作で、これは私のFPSの方法をあまりにも低くしていました。Unreal Engine 4:マルチスレッドフレームワークにReadPixels()を適用する
この問題を解決するために、CaptureComponentとしてカメラにアクセスできる専用のスレッドを作成しようとしていますが、同様のアプローチに従ってください。しかし、FlushRenderingCommands()ブロックはゲームスレッドからしか呼び出せないので、その呼び出しなしでReadPixels()を書き直さなければなりませんでした。(ブロックのない方法で、https://wiki.unrealengine.com/Render_Target_Lookupのチュートリアルに触発されています)。画像が保存されるたびに私のゲーム中のFPSがぎくしゃくする問題に直面しています(これは実際にディスク操作に保存されたものではなく、ピクセルデータアクセスによるものであることを確認しました)。書き直したReadPixels()関数は以下のように見えますが、ここで何がうまくいかないかについていくつかの提案を得ることを望んでいました。私はENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETERがゲーム以外のスレッドから呼び出せるかどうか、それが私の問題の一部であるかどうかはわかりません。
APIPCamera* cam = GameThread->CameraDirector->getCamera(0);
USceneCaptureComponent2D* capture = cam->getCaptureComponent(EPIPCameraType::PIP_CAMERA_TYPE_SCENE, true);
if (capture != nullptr) {
if (capture->TextureTarget != nullptr) {
FTextureRenderTargetResource* RenderResource = capture->TextureTarget->GetRenderTargetResource();
if (RenderResource != nullptr) {
width = capture->TextureTarget->GetSurfaceWidth();
height = capture->TextureTarget->GetSurfaceHeight();
// Read the render target surface data back.
struct FReadSurfaceContext
{
FRenderTarget* SrcRenderTarget;
TArray<FColor>* OutData;
FIntRect Rect;
FReadSurfaceDataFlags Flags;
};
bmp.Reset();
FReadSurfaceContext ReadSurfaceContext =
{
RenderResource,
&bmp,
FIntRect(0, 0, RenderResource->GetSizeXY().X, RenderResource->GetSizeXY().Y),
FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX)
};
ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(
ReadSurfaceCommand,
FReadSurfaceContext, Context, ReadSurfaceContext,
{
RHICmdList.ReadSurfaceData(
Context.SrcRenderTarget->GetRenderTargetTexture(),
Context.Rect,
*Context.OutData,
Context.Flags
);
});
}
}
}
編集:私は気づいたもう一つは、私は私のレンダーターゲットの設定でHDRを無効にします(これは、低品質画像につながる)場合吃音が消えるということですので、それはもっともらしく思われる画像の大きさおそらく、私はそれを実装している方法のために、コアスレッドの1つをまだブロックしています。
また、プロファイリングツールを使って(単一カメラのHDRの場合)見てみました。時間の点で最大のヒットだったイベントの大部分は、「CPUストール:イベント待ち」、「CPUストール:スリープ」私は彼らがGPUが追いつくのを待っていたと推測しています。 – HighVoltage
コメントをいただきありがとう:私がstat unitgraphを実行すると、これは私が見つけたものです:いいえHDR:まともなレートのすべてのスレッド。 HDR:レンダリングスレッドのスパイクが大きくなり、フレームタイミングが急上昇する。時折GPUスレッドの遅れもあります。 i.imgur.com/S1YVGaz.png – HighVoltage
レンダリングスレッドでも 'ReadSurfaceData'メソッドが時間がかかりすぎているようです。 read関数を複数回呼び出すなど、他の間違いがないと仮定すると、ピクセルデータを読み取るこの特定のメソッドを使用すると、マルチスレッドの最適化が不可能になります。生のDirectXを使用することを考えましたか?RHIオブジェクトから直接アクセスすることはできますが、プロジェクトのプラットフォーム依存性は非常に高くなります。 – JKovalsky