Rendering Outside Normal Render Path#
Also take a look at SceneCaptureRenderer: which creates a separate renderer to do captures
C++
RHICreateTargetableShaderResource3D
DrawWindow_RenderThread
FTexture2DRHIRef ViewportRT = bRenderedStereo ? nullptr : ViewportInfo.GetRenderTargetTexture();
FTexture2DRHIRef BackBuffer = (ViewportRT) ? ViewportRT : RHICmdList.GetViewportBackBuffer(ViewportInfo.ViewportRHI);
FResolveParams ResolveParams;
bClear = true; // Force a clear of the UI buffer to black
// Grab HDR backbuffer
RHICmdList.CopyToResolveTarget(FinalBuffer, ViewportInfo.HDRSourceRT, false, ResolveParams);
// UI backbuffer is temp target
BackBuffer = ViewportInfo.UITargetRT;
// Reset the backbuffer as our color render target and also set a depth stencil buffer
FRHIRenderTargetView ColorView(BackBuffer, 0, -1, bClear ? ERenderTargetLoadAction::EClear : ERenderTargetLoadAction::ELoad, ERenderTargetStoreAction::EStore);
FRHIDepthRenderTargetView DepthStencilView(ViewportInfo.DepthStencil, ERenderTargetLoadAction::ENoAction, ERenderTargetStoreAction::ENoAction, ERenderTargetLoadAction::ENoAction, ERenderTargetStoreAction::EStore);
FRHISetRenderTargetsInfo Info(1, &ColorView, DepthStencilView);
// Clear the stencil buffer
RHICmdList.SetRenderTargetsAndClear(Info);
SCOPED_DRAW_EVENT(RHICmdList, SlateUI_Composition);
static const FName RendererModuleName("Renderer");
IRendererModule& RendererModule = FModuleManager::GetModuleChecked<IRendererModule>(RendererModuleName);
const auto FeatureLevel = GMaxRHIFeatureLevel;
auto ShaderMap = GetGlobalShaderMap(FeatureLevel);
// Generate composition LUT
if (bLUTStale)
{
SetRenderTarget(RHICmdList, ViewportInfo.ColorSpaceLUTRT, FTextureRHIRef());
FGraphicsPipelineStateInitializer GraphicsPSOInit;
RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit);
GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI();
GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI();
GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<false, CF_Always>::GetRHI();
TShaderMapRef<FWriteToSliceVS> VertexShader(ShaderMap);
TOptionalShaderMapRef<FWriteToSliceGS> GeometryShader(ShaderMap);
TShaderMapRef<FCompositeLUTGenerationPS> PixelShader(ShaderMap);
const FVolumeBounds VolumeBounds(CompositionLUTSize);
GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GScreenVertexDeclaration.VertexDeclarationRHI;
GraphicsPSOInit.BoundShaderState.VertexShaderRHI = GETSAFERHISHADER_VERTEX(*VertexShader);
GraphicsPSOInit.BoundShaderState.GeometryShaderRHI = GETSAFERHISHADER_GEOMETRY(*GeometryShader);
GraphicsPSOInit.BoundShaderState.PixelShaderRHI = GETSAFERHISHADER_PIXEL(*PixelShader);
GraphicsPSOInit.PrimitiveType = PT_TriangleStrip;
SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit);
VertexShader->SetParameters(RHICmdList, VolumeBounds, FIntVector(VolumeBounds.MaxX - VolumeBounds.MinX));
if(GeometryShader.IsValid())
{
GeometryShader->SetParameters(RHICmdList, VolumeBounds.MinZ);
}
PixelShader->SetParameters(RHICmdList);
RasterizeToVolumeTexture(RHICmdList, VolumeBounds);
FResolveParams ResolveParams;
RHICmdList.CopyToResolveTarget(ViewportInfo.ColorSpaceLUTRT, ViewportInfo.ColorSpaceLUTSRV, false, ResolveParams);
}
// Composition pass
{
FResolveParams ResolveParams;
RHICmdList.CopyToResolveTarget(ViewportInfo.UITargetRT, ViewportInfo.UITargetSRV, false, ResolveParams);
SetRenderTarget(RHICmdList, FinalBuffer, FTextureRHIRef());
FGraphicsPipelineStateInitializer GraphicsPSOInit;
RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit);
GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI();
GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI();
GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<false, CF_Always>::GetRHI();
TShaderMapRef<FScreenVS> VertexShader(ShaderMap);
if (HDROutputDevice == 5 || HDROutputDevice == 6)
{
// ScRGB encoding
TShaderMapRef<FCompositePS<1>> PixelShader(ShaderMap);
GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = RendererModule.GetFilterVertexDeclaration().VertexDeclarationRHI;
GraphicsPSOInit.BoundShaderState.VertexShaderRHI = GETSAFERHISHADER_VERTEX(*VertexShader);
GraphicsPSOInit.BoundShaderState.PixelShaderRHI = GETSAFERHISHADER_PIXEL(*PixelShader);
GraphicsPSOInit.PrimitiveType = PT_TriangleList;
SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit);
PixelShader->SetParameters(RHICmdList, ViewportInfo.UITargetSRV, ViewportInfo.HDRSourceSRV, ViewportInfo.ColorSpaceLUTSRV);
}
else
{
// ST2084 (PQ) encoding
TShaderMapRef<FCompositePS<0>> PixelShader(ShaderMap);
GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = RendererModule.GetFilterVertexDeclaration().VertexDeclarationRHI;
GraphicsPSOInit.BoundShaderState.VertexShaderRHI = GETSAFERHISHADER_VERTEX(*VertexShader);
GraphicsPSOInit.BoundShaderState.PixelShaderRHI = GETSAFERHISHADER_PIXEL(*PixelShader);
GraphicsPSOInit.PrimitiveType = PT_TriangleList;
SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit);
PixelShader->SetParameters(RHICmdList, ViewportInfo.UITargetSRV, ViewportInfo.HDRSourceSRV, ViewportInfo.ColorSpaceLUTSRV);
}
RendererModule.DrawRectangle(
RHICmdList,
0, 0,
ViewportWidth, ViewportHeight,
0, 0,
ViewportWidth, ViewportHeight,
FIntPoint(ViewportWidth, ViewportHeight),
FIntPoint(ViewportWidth, ViewportHeight),
*VertexShader,
EDRF_UseTriangleOptimization);
}
RHICmdList.TransitionResource(EResourceTransitionAccess::EReadable, BackBuffer);