Skip to the content.

UE4提交自定义渲染指令

以渲染线程抓图并且保存到本地为例


ENQUEUE_RENDER_COMMAND

ENQUEUE_RENDER_COMMAND 表示从游戏线程向渲染线程发送渲染指令 该宏传入一个Lamda函数,用该Lamda创造一个GraphTask任务加入TaskGraph等待执行

	ENQUEUE_RENDER_COMMAND(CaptureJobData)([this,TempCaptureComponent = this->CaptureComponent,URL](FRHICommandListImmediate& RHICmdList)
	{
		if(TempCaptureComponent && TempCaptureComponent->TextureTarget)
		{

			//GetRenderTargetResource函数要求在Render线程执行
			FTextureRenderTargetResource* RenderResource = TempCaptureComponent->TextureTarget->GetRenderTargetResource();
			//FTextureRenderTargetResource* RenderResource = TempCaptureComponent->TextureTarget->GameThread_GetRenderTargetResource(); GameThread_GetRenderTargetResource函数会要求游戏线程执行,否则断言无法通过。

			int Width = RenderResource->GetSizeX();
			int Height = RenderResource->GetSizeY();

			TArray<FColor> ImageColorList;
			ImageColorList.AddUninitialized(Width * Height);

			//FTextureRenderTargetResource类成员函数ReadPixels调用FlushRenderingCommands会断言GameThread
			//FlushRenderingCommands只能在GameThread调用,用于等待一帧渲染完毕,这里为了测试
			//实现了自定义的ReadPixels 注释掉FlushRenderingCommands函数的调用
			ReadPixels(RenderResource,ImageColorList);

			FString FullPath = URL;

			//接下来的图像处理以及文件本地保存建议放到独立线程内执行
			TArray<uint8> CompressedBitmap;
			FImageUtils::CompressImageArray(Width,Height,ImageColorList,CompressedBitmap);
			FFileHelper::SaveArrayToFile(CompressedBitmap,*FullPath);
			
		}
		else
		{
			UE_LOG(LogTemp,Error,TEXT("CaptureComponent is NULL or CaptureComponent->TextureTarget is NULL"));
		}
	});