픽셀 데이터에 액세스하고 게임중인 카메라의 이미지를 디스크에 저장하려고합니다. 처음에는 렌더링 대상과 이후에 RenderTarget -> ReadPixels()를 사용하는 것이었지만 ReadPixels()의 기본 구현에는 FlushRenderingCommands()에 대한 호출이 포함되어 있으므로 이미지가 저장 될 때까지 게임 스레드를 차단합니다. 계산 집약적 인 작업이어서 FPS 방식을 너무 낮추었습니다.언리얼 엔진 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을 비활성화합니다 (그러나 이것은 낮은 품질의 이미지 결과) 경우 말더듬은 사라질 것입니다 : 그래서 그럴듯하게 보인다 이미지의 크기 , 아마, 내가 그것을 구현하는 방식 때문에 핵심 스레드 중 하나를 여전히 차단하고있다.
프로파일 링 도구를 통해 단일 카메라 HDR 케이스를 보았습니다. 촬영 한 시간 중 가장 큰 히트를 기록한 대부분의 이벤트에는 "CPU 스톨 : 이벤트 대기 중", "CPU 스톨 : 잠자기" 그 (것)들에 쓰여졌는데, GPU가 따라 잡기를 기다리고 있었다고 나는 추측한다. – HighVoltage
주석 주셔서 감사합니다 : 통계 단위 그래프를 실행할 때, 이것은 내가 찾은 것입니다 : 아니오 HDR : 괜찮은 속도로 모든 스레드. HDR : 렌더링 스레드가 많이 부풀어 올라 프레임 타이밍이 급격히 올라갑니다. 가끔 GPU 스레드가 지연됩니다. i.imgur.com/S1YVGaz.png – HighVoltage
'ReadSurfaceData' 메소드가 렌더링 스레드에서 너무 많은 시간을 들여 보내는 것처럼 보입니다. read 함수를 여러 번 호출하는 것과 같은 다른 실수를하지 않았다면,이 특별한 방법으로 픽셀 데이터를 읽는 것이 멀티 스레딩 최적화를 불가능하게 만듭니다. 원시 DirectX 사용에 대해 생각해 보셨습니까?RHI 객체에서 직접 액세스 할 수 있지만 프로젝트가 플랫폼에 따라 크게 달라집니다. – JKovalsky