void FMediaTextureResource::UpdateDeferredResource(FRHICommandListImmediate& RHICmdList, bool bClearRenderTarget/*=true*/) { FTimespan CurrentFrameTime = VideoBuffer->GetCurrentSampleTime(); TSharedPtr<TArray<uint8>, ESPMode::ThreadSafe> CurrentFrame = VideoBuffer->GetCurrentSample(); if (CurrentFrame.IsValid()) { // draw the latest video frame if (CurrentFrameTime != LastFrameTime) { uint32 Stride = 0; FRHITexture2D* Texture2D = TextureRHI->GetTexture2D(); uint8* TextureBuffer = (uint8*)RHILockTexture2D(Texture2D, 0, RLM_WriteOnly, Stride, false); FMemory::Memcpy(TextureBuffer, CurrentFrame->GetData(), CurrentFrame->Num()); RHIUnlockTexture2D(Texture2D, 0, false); LastFrameTime = CurrentFrameTime; Cleared = false; } } else if (!Cleared || (LastClearColor != Owner->ClearColor)) { // clear texture if video track selected FRHICommandListImmediate& CommandList = FRHICommandListExecutor::GetImmediateCommandList(); SetRenderTarget(CommandList, RenderTargetTextureRHI, FTextureRHIRef()); CommandList.SetViewport(0, 0, 0.0f, Owner->GetSurfaceWidth(), Owner->GetSurfaceHeight(), 1.0f); CommandList.Clear(true, Owner->ClearColor, false, 0.f, false, 0, FIntRect()); CommandList.CopyToResolveTarget(Texture2DRHI, TextureRHI, true, FResolveParams()); LastClearColor = Owner->ClearColor; Cleared = true; } }
void FSteamVRHMD::RenderTexture_RenderThread(FRHICommandListImmediate& RHICmdList, FTexture2DRHIParamRef BackBuffer, FTexture2DRHIParamRef SrcTexture) const { check(IsInRenderingThread()); if (WindowMirrorMode == 0) { return; } const uint32 ViewportWidth = BackBuffer->GetSizeX(); const uint32 ViewportHeight = BackBuffer->GetSizeY(); SetRenderTarget(RHICmdList, BackBuffer, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0, ViewportWidth, ViewportHeight, 1.0f); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); const auto FeatureLevel = GMaxRHIFeatureLevel; auto ShaderMap = GetGlobalShaderMap(FeatureLevel); TShaderMapRef<FScreenVS> VertexShader(ShaderMap); TShaderMapRef<FScreenPS> PixelShader(ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, FeatureLevel, BoundShaderState, RendererModule->GetFilterVertexDeclaration().VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, TStaticSamplerState<SF_Bilinear>::GetRHI(), SrcTexture); if (WindowMirrorMode == 1) { // need to clear when rendering only one eye since the borders won't be touched by the DrawRect below RHICmdList.Clear(true, FLinearColor::Black, false, 0, false, 0, FIntRect()); RendererModule->DrawRectangle( RHICmdList, ViewportWidth / 4, 0, ViewportWidth / 2, ViewportHeight, 0.1f, 0.2f, 0.3f, 0.6f, FIntPoint(ViewportWidth, ViewportHeight), FIntPoint(1, 1), *VertexShader, EDRF_Default); } else if (WindowMirrorMode == 2) { RendererModule->DrawRectangle( RHICmdList, 0, 0, ViewportWidth, ViewportHeight, 0.0f, 0.0f, 1.0f, 1.0f, FIntPoint(ViewportWidth, ViewportHeight), FIntPoint(1, 1), *VertexShader, EDRF_Default); } }
void FRCPassPostProcessAA::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessAA); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntRect SrcRect = View.ViewRect; FIntRect DestRect = View.ViewRect; FIntPoint SrcSize = InputDesc->Extent; FIntPoint DestSize = PassOutputs[0].RenderTargetDesc.Extent; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(0, 0, 0.0f, DestSize.X, DestSize.Y, 1.0f ); // set the state Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); switch(Quality) { case 1: SetShaderTemplAA<1>(Context); break; case 2: SetShaderTemplAA<2>(Context); break; case 3: SetShaderTemplAA<3>(Context); break; case 4: SetShaderTemplAA<4>(Context); break; case 5: SetShaderTemplAA<5>(Context); break; default: SetShaderTemplAA<6>(Context); break; } // Draw a quad mapping scene color to the view's render target TShaderMapRef<FFXAAVS> VertexShader(Context.GetShaderMap()); DrawRectangle( Context.RHICmdList, DestRect.Min.X, DestRect.Min.Y, DestRect.Width(), DestRect.Height(), SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestSize, SrcSize, *VertexShader, EDRF_Default); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FRCPassPostProcessLensBlur::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, PassPostProcessLensBlur); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; FIntPoint TexSize = InputDesc->Extent; // usually 1, 2, 4 or 8 uint32 ScaleToFullRes = GSceneRenderTargets.GetBufferSizeXY().X / TexSize.X; FIntRect ViewRect = FIntRect::DivideAndRoundUp(View.ViewRect, ScaleToFullRes); FIntPoint ViewSize = ViewRect.Size(); const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef(), ESimpleRenderTargetMode::EClearColorToBlack); Context.SetViewportAndCallRHI(ViewRect); // set the state (additive blending) Context.RHICmdList.SetBlendState(TStaticBlendState<CW_RGB, BO_Add, BF_One, BF_One>::GetRHI()); Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FPostProcessLensBlurVS> VertexShader(Context.GetShaderMap()); TShaderMapRef<FPostProcessLensBlurPS> PixelShader(Context.GetShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GEmptyVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); uint32 TileSize = 1; FIntPoint TileCount = ViewSize / TileSize; float PixelKernelSize = PercentKernelSize / 100.0f * ViewSize.X; VertexShader->SetParameters(Context, TileCount, TileSize, PixelKernelSize, Threshold); PixelShader->SetParameters(Context, PixelKernelSize); Context.RHICmdList.SetStreamSource(0, NULL, 0, 0); // needs to be the same on shader side (faster on NVIDIA and AMD) int32 QuadsPerInstance = 4; Context.RHICmdList.DrawPrimitive(PT_TriangleList, 0, 2, FMath::DivideAndRoundUp(TileCount.X * TileCount.Y, QuadsPerInstance)); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FRCPassPostProcessMorpheus::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessMorpheus); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntRect SrcRect = View.ViewRect; FIntRect DestRect = View.UnscaledViewRect; FIntPoint SrcSize = InputDesc->Extent; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(DestRect); // set the state Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FPostProcessMorpheusVS> VertexShader(Context.GetShaderMap()); TShaderMapRef<FPostProcessMorpheusPS> PixelShader(Context.GetShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); FMatrix QuadTexTransform; FMatrix QuadPosTransform = FMatrix::Identity; PixelShader->SetPS(Context, SrcRect, SrcSize, View.StereoPass, QuadTexTransform); // Draw a quad mapping scene color to the view's render target DrawTransformedRectangle( Context.RHICmdList, 0, 0, DestRect.Width(), DestRect.Height(), QuadPosTransform, SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), QuadTexTransform, DestRect.Size(), SrcSize ); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FRCPassPostProcessVisualizeBloomOverlay::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, VisualizeBloomOverlay); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); check(InputDesc && "Input is not hooked up correctly"); const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntPoint SrcSize = InputDesc->Extent; FIntPoint DestSize = PassOutputs[0].RenderTargetDesc.Extent; // e.g. 4 means the input texture is 4x smaller than the buffer size uint32 ScaleFactor = GSceneRenderTargets.GetBufferSizeXY().X / SrcSize.X; FIntRect SrcRect = View.ViewRect / ScaleFactor; FIntRect DestRect = SrcRect; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef()); // is optimized away if possible (RT size=view size, ) Context.RHICmdList.Clear(true, FLinearColor(0, 0, 0, 0), false, 1.0f, false, 0, DestRect); Context.SetViewportAndCallRHI(0, 0, 0.0f, DestRect.Width(), DestRect.Height(), 1.0f ); // set the state Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FPostProcessVS> VertexShader(Context.GetShaderMap()); TShaderMapRef<FPostProcessVisualizeBloomOverlayPS> PixelShader(Context.GetShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(Context); VertexShader->SetParameters(Context); // Draw a quad mapping scene color to the view's render target DrawRectangle( Context.RHICmdList, DestRect.Min.X, DestRect.Min.Y, DestRect.Width(), DestRect.Height(), SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestRect.Size(), SrcSize, *VertexShader, EDRF_UseTriangleOptimization); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FRCPassPostProcessVisualizeLPV::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, VisualizeLPV); const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); // const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); const TRefCountPtr<IPooledRenderTarget> RenderTarget = GetInput(ePId_Input0)->GetOutput()->PooledRenderTarget; const FSceneRenderTargetItem& DestRenderTarget = RenderTarget->GetRenderTargetItem(); // Set the view family's render target/viewport. SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef()); { FRenderTargetTemp TempRenderTarget(View, (const FTexture2DRHIRef&)DestRenderTarget.TargetableTexture); FCanvas Canvas(&TempRenderTarget, NULL, ViewFamily.CurrentRealTime, ViewFamily.CurrentWorldTime, ViewFamily.DeltaWorldTime, View.GetFeatureLevel()); float X = 30; float Y = 28; const float YStep = 14; const float ColumnWidth = 250; Canvas.DrawShadowedString( X, Y += YStep, TEXT("VisualizeLightPropagationVolume"), GetStatsFont(), FLinearColor(0.2f, 0.2f, 1)); Y += YStep; const FLightPropagationVolumeSettings& Dest = View.FinalPostProcessSettings.BlendableManager.GetSingleFinalDataConst<FLightPropagationVolumeSettings>(); #define ENTRY(name)\ Canvas.DrawShadowedString( X, Y += YStep, TEXT(#name) TEXT(":"), GetStatsFont(), FLinearColor(1, 1, 1));\ Canvas.DrawShadowedString( X + ColumnWidth, Y, *FString::Printf(TEXT("%g"), Dest.name), GetStatsFont(), FLinearColor(1, 1, 1)); ENTRY(LPVIntensity) ENTRY(LPVVplInjectionBias) ENTRY(LPVSize) ENTRY(LPVSecondaryOcclusionIntensity) ENTRY(LPVSecondaryBounceIntensity) ENTRY(LPVGeometryVolumeBias) ENTRY(LPVEmissiveInjectionIntensity) ENTRY(LPVDirectionalOcclusionIntensity) ENTRY(LPVDirectionalOcclusionRadius) ENTRY(LPVDiffuseOcclusionExponent) ENTRY(LPVSpecularOcclusionExponent) ENTRY(LPVDiffuseOcclusionIntensity) ENTRY(LPVSpecularOcclusionIntensity) #undef ENTRY Canvas.Flush_RenderThread(Context.RHICmdList); } Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); // to satify following passws FRenderingCompositeOutput* Output = GetOutput(ePId_Output0); Output->PooledRenderTarget = RenderTarget; }
void FRCPassPostProcessHistogramReduce::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessHistogramReduce); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntPoint SrcSize = InputDesc->Extent; FIntPoint DestSize = PassOutputs[0].RenderTargetDesc.Extent; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef()); // set the state Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FPostProcessVS> VertexShader(Context.GetShaderMap()); TShaderMapRef<FPostProcessHistogramReducePS> PixelShader(Context.GetShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); // we currently assume the input is half res, one full res pixel less to avoid getting bilinear filtered input FIntPoint GatherExtent = (View.ViewRect.Size() - FIntPoint(1, 1)) / 2; uint32 LoopSizeValue = ComputeLoopSize(GatherExtent); PixelShader->SetPS(Context, LoopSizeValue); DrawPostProcessPass( Context.RHICmdList, 0, 0, DestSize.X, DestSize.Y, 0, 0, SrcSize.X, 0, DestSize, SrcSize, *VertexShader, View.StereoPass, Context.HasHmdMesh(), EDRF_UseTriangleOptimization); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FRCPassPostProcessVisualizeMotionBlur::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(VisualizeMotionBlur, DEC_SCENE_ITEMS); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; FIntPoint TexSize = InputDesc->Extent; // we assume the input and output is full resolution FIntPoint SrcSize = InputDesc->Extent; FIntPoint DestSize = PassOutputs[0].RenderTargetDesc.Extent; // e.g. 4 means the input texture is 4x smaller than the buffer size uint32 ScaleFactor = GSceneRenderTargets.GetBufferSizeXY().X / SrcSize.X; FIntRect SrcRect = FIntRect::DivideAndRoundUp(View.ViewRect, ScaleFactor); FIntRect DestRect = SrcRect; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef()); // is optimized away if possible (RT size=view size, ) RHIClear(true, FLinearColor::Black, false, 1.0f, false, 0, SrcRect); Context.SetViewportAndCallRHI(SrcRect); // set the state RHISetBlendState(TStaticBlendState<>::GetRHI()); RHISetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI()); // Quality 0: visualize SetMotionBlurShaderTempl<0>(Context); // Draw a quad mapping scene color to the view's render target DrawRectangle( 0, 0, SrcRect.Width(), SrcRect.Height(), SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), SrcRect.Size(), SrcSize, EDRF_UseTriangleOptimization); RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FRCPassPostProcessHistogram::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(PostProcessHistogram, DEC_SCENE_ITEMS); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntPoint SrcSize = InputDesc->Extent; FIntRect DestRect = View.ViewRect; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); TShaderMapRef<FPostProcessHistogramCS> ComputeShader(GetGlobalShaderMap()); RHISetComputeShader(ComputeShader->GetComputeShader()); RHISetRenderTarget(FTextureRHIRef(), FTextureRHIRef()); // set destination check(DestRenderTarget.UAV); RHISetUAVParameter(ComputeShader->GetComputeShader(), ComputeShader->HistogramRWTexture.GetBaseIndex(), DestRenderTarget.UAV); // we currently assume the input is half res, one full res pixel less to avoid getting bilinear filtered input FIntPoint GatherExtent = (DestRect.Size() - FIntPoint(1, 1)) / 2; FIntPoint ThreadGroupCountValue = ComputeThreadGroupCount(GatherExtent); ComputeShader->SetCS(Context, ThreadGroupCountValue, (DestRect.Min + FIntPoint(1, 1)) / 2, GatherExtent); DispatchComputeShader(*ComputeShader, ThreadGroupCountValue.X, ThreadGroupCountValue.Y, 1); // un-set destination RHISetUAVParameter(ComputeShader->GetComputeShader(), ComputeShader->HistogramRWTexture.GetBaseIndex(), NULL); RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FRCPassPostProcessHistogram::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessHistogram); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntPoint SrcSize = InputDesc->Extent; FIntRect DestRect = View.ViewRect; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); TShaderMapRef<FPostProcessHistogramCS> ComputeShader(Context.GetShaderMap()); SetRenderTarget(Context.RHICmdList, FTextureRHIRef(), FTextureRHIRef()); Context.RHICmdList.SetComputeShader(ComputeShader->GetComputeShader()); // set destination check(DestRenderTarget.UAV); Context.RHICmdList.TransitionResource(EResourceTransitionAccess::ERWBarrier, EResourceTransitionPipeline::EGfxToCompute, DestRenderTarget.UAV); Context.RHICmdList.SetUAVParameter(ComputeShader->GetComputeShader(), ComputeShader->HistogramRWTexture.GetBaseIndex(), DestRenderTarget.UAV); FIntPoint GatherExtent = ComputeGatherExtent(View); FIntPoint ThreadGroupCountValue = ComputeThreadGroupCount(GatherExtent); ComputeShader->SetCS(Context.RHICmdList, Context, ThreadGroupCountValue, (DestRect.Min + FIntPoint(1, 1)) / 2, GatherExtent); DispatchComputeShader(Context.RHICmdList, *ComputeShader, ThreadGroupCountValue.X, ThreadGroupCountValue.Y, 1); // un-set destination Context.RHICmdList.SetUAVParameter(ComputeShader->GetComputeShader(), ComputeShader->HistogramRWTexture.GetBaseIndex(), NULL); Context.RHICmdList.TransitionResource(EResourceTransitionAccess::EReadable, EResourceTransitionPipeline::EComputeToGfx, DestRenderTarget.UAV); ensureMsgf(DestRenderTarget.TargetableTexture == DestRenderTarget.ShaderResourceTexture, TEXT("%s should be resolved to a separate SRV"), *DestRenderTarget.TargetableTexture->GetName().ToString()); }
void FRCPassPostProcessVelocityFlatten::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessVelocityFlatten); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); const FSceneRenderTargetItem& DestRenderTarget0 = PassOutputs[0].RequestSurface(Context); const FSceneRenderTargetItem& DestRenderTarget1 = PassOutputs[1].RequestSurface(Context); //const FSceneRenderTargetItem& DestRenderTarget2 = PassOutputs[2].RequestSurface(Context); TShaderMapRef< FPostProcessVelocityFlattenCS > ComputeShader( Context.GetShaderMap() ); Context.RHICmdList.SetComputeShader(ComputeShader->GetComputeShader()); SetRenderTarget(Context.RHICmdList, FTextureRHIRef(), FTextureRHIRef()); // set destination Context.RHICmdList.SetUAVParameter( ComputeShader->GetComputeShader(), ComputeShader->OutVelocityFlat.GetBaseIndex(), DestRenderTarget0.UAV ); //Context.RHICmdList.SetUAVParameter( ComputeShader->GetComputeShader(), ComputeShader->OutPackedVelocityDepth.GetBaseIndex(), DestRenderTarget1.UAV ); Context.RHICmdList.SetUAVParameter( ComputeShader->GetComputeShader(), ComputeShader->OutMaxTileVelocity.GetBaseIndex(), DestRenderTarget1.UAV ); ComputeShader->SetCS(Context.RHICmdList, Context, View ); FIntPoint ThreadGroupCountValue = ComputeThreadGroupCount( View.ViewRect.Size() ); DispatchComputeShader(Context.RHICmdList, *ComputeShader, ThreadGroupCountValue.X, ThreadGroupCountValue.Y, 1); // un-set destination Context.RHICmdList.SetUAVParameter( ComputeShader->GetComputeShader(), ComputeShader->OutVelocityFlat.GetBaseIndex(), NULL ); //Context.RHICmdList.SetUAVParameter( ComputeShader->GetComputeShader(), ComputeShader->OutPackedVelocityDepth.GetBaseIndex(), NULL ); Context.RHICmdList.SetUAVParameter( ComputeShader->GetComputeShader(), ComputeShader->OutMaxTileVelocity.GetBaseIndex(), NULL ); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget0.TargetableTexture, DestRenderTarget0.ShaderResourceTexture, false, FResolveParams()); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget1.TargetableTexture, DestRenderTarget1.ShaderResourceTexture, false, FResolveParams()); //Context.RHICmdList.CopyToResolveTarget(DestRenderTarget1.TargetableTexture, DestRenderTarget2.ShaderResourceTexture, false, FResolveParams()); }
void FRCPassPostProcessVisualizeComplexity::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessVisualizeComplexity); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntRect SrcRect = View.ViewRect; FIntRect DestRect = View.UnscaledViewRect; FIntPoint SrcSize = InputDesc->Extent; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(DestRect); // turn off culling and blending Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI()); Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); // turn off depth reads/writes Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); //reuse this generic vertex shader TShaderMapRef<FShaderComplexityApplyVS> VertexShader(Context.GetShaderMap()); TShaderMapRef<FShaderComplexityApplyPS> PixelShader(Context.GetShaderMap()); static FGlobalBoundShaderState ShaderComplexityBoundShaderState; SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), ShaderComplexityBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(Context, Colors); DrawRectangle( Context.RHICmdList, 0, 0, DestRect.Width(), DestRect.Height(), SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestRect.Size(), SrcSize, *VertexShader, EDRF_UseTriangleOptimization); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FOculusRiftHMD::CopyTexture_RenderThread(FRHICommandListImmediate& RHICmdList, FTexture2DRHIParamRef DstTexture, FTexture2DRHIParamRef SrcTexture, FIntRect DstRect, FIntRect SrcRect) const { check(IsInRenderingThread()); if (DstRect.IsEmpty()) { DstRect = FIntRect(0, 0, DstTexture->GetSizeX(), DstTexture->GetSizeY()); } const uint32 ViewportWidth = DstRect.Width(); const uint32 ViewportHeight = DstRect.Height(); const FIntPoint TargetSize(ViewportWidth, ViewportHeight); const float SrcTextureWidth = SrcTexture->GetSizeX(); const float SrcTextureHeight = SrcTexture->GetSizeY(); float U = 0.f, V = 0.f, USize = 1.f, VSize = 1.f; if (!SrcRect.IsEmpty()) { U = SrcRect.Min.X / SrcTextureWidth; V = SrcRect.Min.Y / SrcTextureHeight; USize = SrcRect.Width() / SrcTextureWidth; VSize = SrcRect.Height() / SrcTextureHeight; } SetRenderTarget(RHICmdList, DstTexture, FTextureRHIRef()); RHICmdList.SetViewport(DstRect.Min.X, DstRect.Min.Y, 0, DstRect.Max.X, DstRect.Max.Y, 1.0f); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); const auto FeatureLevel = GMaxRHIFeatureLevel; auto ShaderMap = GetGlobalShaderMap(FeatureLevel); TShaderMapRef<FScreenVS> VertexShader(ShaderMap); TShaderMapRef<FScreenPS> PixelShader(ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, FeatureLevel, BoundShaderState, RendererModule->GetFilterVertexDeclaration().VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, TStaticSamplerState<SF_Bilinear>::GetRHI(), SrcTexture); RendererModule->DrawRectangle( RHICmdList, 0, 0, ViewportWidth, ViewportHeight, U, V, USize, VSize, TargetSize, FIntPoint(1, 1), *VertexShader, EDRF_Default); }
void FRCPassPostProcessSceneColorFringe::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, SceneColorFringe); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(View.ViewRect); // set the state Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FPostProcessSceneColorFringeVS> VertexShader(Context.GetShaderMap()); TShaderMapRef<FPostProcessSceneColorFringePS> PixelShader(Context.GetShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(Context); VertexShader->SetParameters(Context); // Draw a quad mapping scene color to the view's render target DrawRectangle( Context.RHICmdList, 0, 0, View.ViewRect.Width(), View.ViewRect.Height(), View.ViewRect.Min.X, View.ViewRect.Min.Y, View.ViewRect.Width(), View.ViewRect.Height(), View.ViewRect.Size(), FSceneRenderTargets::Get(Context.RHICmdList).GetBufferSizeXY(), *VertexShader, EDRF_UseTriangleOptimization); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FOpenGLDynamicRHI::RHIBeginDrawingViewport(FViewportRHIParamRef ViewportRHI, FTextureRHIParamRef RenderTarget) { VERIFY_GL_SCOPE(); DYNAMIC_CAST_OPENGLRESOURCE(Viewport,Viewport); SCOPE_CYCLE_COUNTER(STAT_OpenGLPresentTime); check(!DrawingViewport); DrawingViewport = Viewport; bRevertToSharedContextAfterDrawingViewport = false; EOpenGLCurrentContext CurrentContext = PlatformOpenGLCurrentContext( PlatformDevice ); if( CurrentContext != CONTEXT_Rendering ) { check(CurrentContext == CONTEXT_Shared); check(!bIsRenderingContextAcquired || !GUseThreadedRendering); bRevertToSharedContextAfterDrawingViewport = true; PlatformRenderingContextSetup(PlatformDevice); } if(!GPUProfilingData.FrameTiming.IsInitialized()) { GPUProfilingData.FrameTiming.InitResource(); } // Set the render target and viewport. if( RenderTarget ) { FRHIRenderTargetView RTV(RenderTarget); RHISetRenderTargets(1, &RTV, FTextureRHIRef(), 0, NULL); } else { FRHIRenderTargetView RTV(DrawingViewport->GetBackBuffer()); RHISetRenderTargets(1, &RTV, FTextureRHIRef(), 0, NULL); } }
void AllocateOrReuseLightShaftRenderTarget(FRHICommandListImmediate& RHICmdList, TRefCountPtr<IPooledRenderTarget>& Target, const TCHAR* Name) { if (!Target) { EPixelFormat LightShaftFilterBufferFormat = PF_FloatRGB; const FIntPoint BufferSize = FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(); FIntPoint LightShaftSize(FMath::Max<uint32>(BufferSize.X / GetLightShaftDownsampleFactor(), 1), FMath::Max<uint32>(BufferSize.Y / GetLightShaftDownsampleFactor(), 1)); FPooledRenderTargetDesc Desc(FPooledRenderTargetDesc::Create2DDesc(LightShaftSize, LightShaftFilterBufferFormat, FClearValueBinding::None, TexCreate_None, TexCreate_RenderTargetable, false)); GRenderTargetPool.FindFreeElement(Desc, Target, Name); SetRenderTarget(RHICmdList, Target->GetRenderTargetItem().TargetableTexture, FTextureRHIRef()); RHICmdList.Clear(true, FLinearColor(0, 0, 0, 0), false, 1.0f, false, 0, FIntRect()); } }
void FRCPassPostProcessHMD::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessHMD, DEC_SCENE_ITEMS); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); const FIntRect SrcRect = View.ViewRect; const FIntRect DestRect = View.UnscaledViewRect; const FIntPoint SrcSize = InputDesc->Extent; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(DestRect); Context.RHICmdList.Clear(true, FLinearColor::Black, false, 1.0f, false, 0, FIntRect()); // set the state Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); FMatrix QuadTexTransform = FMatrix::Identity; FMatrix QuadPosTransform = FMatrix::Identity; check(GEngine->HMDDevice.IsValid()); { TShaderMapRef<FPostProcessHMDVS<false> > VertexShader(Context.GetShaderMap()); TShaderMapRef<FPostProcessHMDPS<false> > PixelShader(Context.GetShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GDistortionVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); VertexShader->SetVS(Context, View.StereoPass); PixelShader->SetPS(Context, SrcRect, SrcSize, View.StereoPass, QuadTexTransform); } GEngine->HMDDevice->DrawDistortionMesh_RenderThread(Context, View, SrcSize); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void UCodecMovieFallback::GetFrame( class FTextureMovieResource* InTextureMovieResource ) { CurrentTime += 1.f / GetFrameRate(); if( CurrentTime > PlaybackDuration ) { CurrentTime = 0.f; } if( InTextureMovieResource && InTextureMovieResource->IsInitialized() ) { FLinearColor ClearColor(1.f,CurrentTime/PlaybackDuration,0.f,1.f); RHISetRenderTarget(InTextureMovieResource->GetRenderTargetTexture(),FTextureRHIRef()); RHIClear(true,ClearColor,false,0.f,false,0, FIntRect()); RHICopyToResolveTarget(InTextureMovieResource->GetRenderTargetTexture(),InTextureMovieResource->TextureRHI,false,FResolveParams()); } }
void FD3D11DynamicRHI::IssueLongGPUTask() { if (GMaxRHIFeatureLevel >= ERHIFeatureLevel::SM4) { int32 LargestViewportIndex = INDEX_NONE; int32 LargestViewportPixels = 0; for (int32 ViewportIndex = 0; ViewportIndex < Viewports.Num(); ViewportIndex++) { FD3D11Viewport* Viewport = Viewports[ViewportIndex]; if (Viewport->GetSizeXY().X * Viewport->GetSizeXY().Y > LargestViewportPixels) { LargestViewportPixels = Viewport->GetSizeXY().X * Viewport->GetSizeXY().Y; LargestViewportIndex = ViewportIndex; } } if (LargestViewportIndex >= 0) { FD3D11Viewport* Viewport = Viewports[LargestViewportIndex]; FRHICommandList_RecursiveHazardous RHICmdList(this); SetRenderTarget(RHICmdList, Viewport->GetBackBuffer(), FTextureRHIRef()); RHICmdList.SetBlendState(TStaticBlendState<CW_RGBA, BO_Add, BF_One, BF_One>::GetRHI(), FLinearColor::Black); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI(), 0); RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI()); auto ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel); TShaderMapRef<TOneColorVS<true> > VertexShader(ShaderMap); TShaderMapRef<FLongGPUTaskPS> PixelShader(ShaderMap); RHICmdList.SetLocalBoundShaderState(RHICmdList.BuildLocalBoundShaderState(GD3D11Vector4VertexDeclaration.VertexDeclarationRHI, VertexShader->GetVertexShader(), FHullShaderRHIRef(), FDomainShaderRHIRef(), PixelShader->GetPixelShader(), FGeometryShaderRHIRef())); // Draw a fullscreen quad FVector4 Vertices[4]; Vertices[0].Set( -1.0f, 1.0f, 0, 1.0f ); Vertices[1].Set( 1.0f, 1.0f, 0, 1.0f ); Vertices[2].Set( -1.0f, -1.0f, 0, 1.0f ); Vertices[3].Set( 1.0f, -1.0f, 0, 1.0f ); DrawPrimitiveUP(RHICmdList, PT_TriangleStrip, 2, Vertices, sizeof(Vertices[0])); // Implicit flush. Always call flush when using a command list in RHI implementations before doing anything else. This is super hazardous. } } }
void FD3D11DynamicRHI::RHIBeginDrawingViewport(FViewportRHIParamRef ViewportRHI, FTextureRHIParamRef RenderTarget) { DYNAMIC_CAST_D3D11RESOURCE(Viewport,Viewport); SCOPE_CYCLE_COUNTER(STAT_D3D11PresentTime); check(!DrawingViewport); DrawingViewport = Viewport; // Set the render target and viewport. if( RenderTarget == NULL ) { RenderTarget = Viewport->GetBackBuffer(); } FRHIRenderTargetView View(RenderTarget); RHISetRenderTargets(1,&View,FTextureRHIRef(),0,NULL); // Set an initially disabled scissor rect. RHISetScissorRect(false,0,0,0,0); }
void FRCPassPostProcessBusyWait::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(BusyWait, DEC_SCENE_ITEMS); const FSceneView& View = Context.View; FIntRect SrcRect = View.ViewRect; FIntRect DestRect = View.UnscaledViewRect; const FSceneRenderTargetItem& DestRenderTarget = GSceneRenderTargets.LightAttenuation->GetRenderTargetItem(); // Set the view family's render target/viewport. RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(DestRect); // set the state RHISetBlendState(TStaticBlendState<>::GetRHI()); RHISetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI()); TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessBusyWaitPS> PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetPS(Context); // Draw a quad mapping scene color to the view's render target DrawRectangle( 0, 0, DestRect.Width(), DestRect.Height(), SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestRect.Size(), SrcRect.Size(), EDRF_UseTriangleOptimization); RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FRCPassPostProcessDOFRecombine::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, DOFRecombine); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input1); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const auto FeatureLevel = Context.GetFeatureLevel(); auto ShaderMap = Context.GetShaderMap(); FIntPoint TexSize = InputDesc->Extent; // usually 1, 2, 4 or 8 uint32 ScaleToFullRes = FSceneRenderTargets::Get(Context.RHICmdList).GetBufferSizeXY().X / TexSize.X; FIntRect HalfResViewRect = View.ViewRect / ScaleToFullRes; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef()); // is optimized away if possible (RT size=view size, ) Context.RHICmdList.Clear(true, FLinearColor::Black, false, 1.0f, false, 0, View.ViewRect); Context.SetViewportAndCallRHI(View.ViewRect); // set the state Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FPostProcessVS> VertexShader(ShaderMap); if (bNearBlurEnabled) { static FGlobalBoundShaderState BoundShaderState; TShaderMapRef< FPostProcessDOFRecombinePS<1> > PixelShader(ShaderMap); SetGlobalBoundShaderState(Context.RHICmdList, FeatureLevel, BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(Context); } else { static FGlobalBoundShaderState BoundShaderState; TShaderMapRef< FPostProcessDOFRecombinePS<0> > PixelShader(ShaderMap); SetGlobalBoundShaderState(Context.RHICmdList, FeatureLevel, BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(Context); } VertexShader->SetParameters(Context); DrawPostProcessPass( Context.RHICmdList, 0, 0, View.ViewRect.Width(), View.ViewRect.Height(), HalfResViewRect.Min.X, HalfResViewRect.Min.Y, HalfResViewRect.Width(), HalfResViewRect.Height(), View.ViewRect.Size(), TexSize, *VertexShader, View.StereoPass, Context.HasHmdMesh(), EDRF_UseTriangleOptimization); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FRCPassPostProcessPassThrough::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(PassThrough, DEC_SCENE_ITEMS); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; FIntPoint TexSize = InputDesc->Extent; // we assume the input and output is full resolution FIntPoint SrcSize = InputDesc->Extent; FIntPoint DestSize = Dest ? Dest->GetDesc().Extent : PassOutputs[0].RenderTargetDesc.Extent; // e.g. 4 means the input texture is 4x smaller than the buffer size uint32 InputScaleFactor = GSceneRenderTargets.GetBufferSizeXY().X / SrcSize.X; uint32 OutputScaleFactor = GSceneRenderTargets.GetBufferSizeXY().X / DestSize.X; FIntRect SrcRect = View.ViewRect / InputScaleFactor; FIntRect DestRect = View.ViewRect / OutputScaleFactor; const FSceneRenderTargetItem& DestRenderTarget = Dest ? Dest->GetRenderTargetItem() : PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(0, 0, 0.0f, DestSize.X, DestSize.Y, 1.0f); // set the state if(bAdditiveBlend) { RHISetBlendState(TStaticBlendState<CW_RGB,BO_Add,BF_One,BF_One,BO_Add,BF_One,BF_One>::GetRHI()); } else { RHISetBlendState(TStaticBlendState<>::GetRHI()); } RHISetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI()); TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessPassThroughPS> PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); VertexShader->SetParameters(Context); PixelShader->SetParameters(Context); // Draw a quad mapping scene color to the view's render target DrawRectangle( DestRect.Min.X, DestRect.Min.Y, DestRect.Width(), DestRect.Height(), SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestSize, SrcSize, EDRF_UseTriangleOptimization); RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FGoogleVRHMD::RenderTexture_RenderThread(FRHICommandListImmediate& RHICmdList, FTexture2DRHIParamRef BackBuffer, FTexture2DRHIParamRef SrcTexture) const { check(IsInRenderingThread()); const uint32 ViewportWidth = BackBuffer->GetSizeX(); const uint32 ViewportHeight = BackBuffer->GetSizeY(); const uint32 TextureWidth = SrcTexture->GetSizeX(); const uint32 TextureHeight = SrcTexture->GetSizeY(); //UE_LOG(LogHMD, Log, TEXT("RenderTexture_RenderThread() Viewport:(%d, %d) Texture:(%d, %d) BackBuffer=%p SrcTexture=%p"), ViewportWidth, ViewportHeight, TextureWidth, TextureHeight, BackBuffer, SrcTexture); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); #if GOOGLEVRHMD_SUPPORTED_PLATFORMS if(IsUsingGVRApiDistortionCorrection()) { if(!bDistortionCorrectionEnabled) { return; } // Perform render if(!bUseOffscreenFramebuffers) { // With proper resolution scaling, this should always be true! check(ViewportWidth == TextureWidth); check(ViewportHeight == TextureHeight); // Set target to back buffer SetRenderTarget(RHICmdList, BackBuffer, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0, ViewportWidth, ViewportHeight, 1.0f); ResolvePendingRenderTarget(RHICmdList, RendererModule); gvr_distort_to_screen(GVRAPI, *reinterpret_cast<GLuint*>(SrcTexture->GetNativeResource()), CachedDistortedRenderTextureParams, &CachedPose, &CachedFuturePoseTime); } else { if(!IsDeviceScanlineRacingEnabled()) { // With proper resolution scaling, this should always be true! check(ViewportWidth == TextureWidth); check(ViewportHeight == TextureHeight); // Set target to back buffer SetRenderTarget(RHICmdList, BackBuffer, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0, ViewportWidth, ViewportHeight, 1.0f); ResolvePendingRenderTarget(RHICmdList, RendererModule); } gvr_distort_offscreen_framebuffer_to_screen(GVRAPI, CustomPresent->GetFrameBufferId(), CachedDistortedRenderTextureParams, &CachedPose, &CachedFuturePoseTime); } } else // falls through on purpose #endif // GOOGLEVRHMD_SUPPORTED_PLATFORMS // Just render directly to output { SetRenderTarget(RHICmdList, BackBuffer, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0, ViewportWidth, ViewportHeight, 1.0f); const auto FeatureLevel = GMaxRHIFeatureLevel; auto ShaderMap = GetGlobalShaderMap(FeatureLevel); TShaderMapRef<FScreenVS> VertexShader(ShaderMap); TShaderMapRef<FScreenPS> PixelShader(ShaderMap); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(RHICmdList, FeatureLevel, BoundShaderState, RendererModule->GetFilterVertexDeclaration().VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetParameters(RHICmdList, TStaticSamplerState<SF_Bilinear>::GetRHI(), SrcTexture); RendererModule->DrawRectangle( RHICmdList, 0, 0, ViewportWidth, ViewportHeight, 0.0f, 0.0f, 1.0f, 1.0f, FIntPoint(ViewportWidth, ViewportHeight), FIntPoint(1, 1), *VertexShader, EDRF_Default); } }
void FRCPassPostProcessVisualizeShadingModels::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessVisualizeShadingModels); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); const FSceneView& View = Context.View; const FViewInfo& ViewInfo = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntRect SrcRect = View.ViewRect; FIntRect DestRect = View.ViewRect; FIntPoint SrcSize = InputDesc->Extent; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. SetRenderTarget(Context.RHICmdList, DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(DestRect); // set the state Context.RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FPostProcessVS> VertexShader(Context.GetShaderMap()); TShaderMapRef<FPostProcessVisualizeShadingModelsPS> PixelShader(Context.GetShaderMap()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetPS(Context, ((FViewInfo&)View).ShadingModelMaskInView); // Draw a quad mapping scene color to the view's render target DrawRectangle( Context.RHICmdList, DestRect.Min.X, DestRect.Min.Y, DestRect.Width(), DestRect.Height(), SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestRect.Size(), SrcSize, *VertexShader, EDRF_UseTriangleOptimization); FRenderTargetTemp TempRenderTarget(View, (const FTexture2DRHIRef&)DestRenderTarget.TargetableTexture); FCanvas Canvas(&TempRenderTarget, NULL, 0, 0, 0, Context.GetFeatureLevel()); float X = 30; float Y = 28; const float YStep = 14; const float ColumnWidth = 250; FString Line; Canvas.DrawShadowedString( X, Y += YStep, TEXT("Visualize ShadingModels (mostly to track down bugs)"), GetStatsFont(), FLinearColor(1, 1, 1)); Y = 160 - YStep - 4; uint32 Value = ((FViewInfo&)View).ShadingModelMaskInView; Line = FString::Printf(TEXT("View.ShadingModelMaskInView = 0x%x"), Value); Canvas.DrawShadowedString( X, Y, *Line, GetStatsFont(), FLinearColor(0.5f, 0.5f, 0.5f)); Y += YStep; UEnum* Enum = FindObject<UEnum>(NULL, TEXT("Engine.EMaterialShadingModel")); check(Enum); Y += 5; for(uint32 i = 0; i < MSM_MAX; ++i) { FString Name = Enum->GetEnumName(i); Line = FString::Printf(TEXT("%d. %s"), i, *Name); bool bThere = (Value & (1 << i)) != 0; Canvas.DrawShadowedString(X + 30, Y, *Line, GetStatsFont(), bThere ? FLinearColor(1, 1, 1) : FLinearColor(0, 0, 0) ); Y += 20; } Line = FString::Printf(TEXT("(On CPU, based on what gets rendered)")); Canvas.DrawShadowedString( X, Y, *Line, GetStatsFont(), FLinearColor(0.5f, 0.5f, 0.5f)); Y += YStep; Canvas.Flush_RenderThread(Context.RHICmdList); Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); // AdjustGBufferRefCount(1) call is done in constructor FSceneRenderTargets::Get(Context.RHICmdList).AdjustGBufferRefCount(Context.RHICmdList, -1); }
void FinishOcclusionTerm(FRHICommandList& RHICmdList, const FViewInfo& View, const FLightSceneInfo* const LightSceneInfo, TRefCountPtr<IPooledRenderTarget>& LightShaftsSource, TRefCountPtr<IPooledRenderTarget>& LightShaftsDest) { TShaderMapRef<FScreenVS> ScreenVertexShader(View.ShaderMap); const FIntPoint BufferSize = FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(); const uint32 DownsampleFactor = GetLightShaftDownsampleFactor(); const FIntPoint FilterBufferSize = BufferSize / DownsampleFactor; const FIntPoint DownSampledXY = View.ViewRect.Min / DownsampleFactor; const uint32 DownsampledSizeX = View.ViewRect.Width() / DownsampleFactor; const uint32 DownsampledSizeY = View.ViewRect.Height() / DownsampleFactor; SetRenderTarget(RHICmdList, LightShaftsDest->GetRenderTargetItem().TargetableTexture, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0.0f, FilterBufferSize.X, FilterBufferSize.Y, 1.0f); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FFinishOcclusionPixelShader> MaskOcclusionTermPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), AccumulateTermBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *ScreenVertexShader, *MaskOcclusionTermPixelShader); /// ? MaskOcclusionTermPixelShader->SetParameters(RHICmdList, LightSceneInfo, View, LightShaftsSource); { // Apply a radial blur to the bloom and occlusion mask DrawRectangle( RHICmdList, DownSampledXY.X, DownSampledXY.Y, DownsampledSizeX, DownsampledSizeY, DownSampledXY.X, DownSampledXY.Y, DownsampledSizeX, DownsampledSizeY, FilterBufferSize, FilterBufferSize, *ScreenVertexShader, EDRF_UseTriangleOptimization); } RHICmdList.CopyToResolveTarget(LightShaftsDest->GetRenderTargetItem().TargetableTexture, LightShaftsDest->GetRenderTargetItem().ShaderResourceTexture, false, FResolveParams()); }
/** Applies screen space radial blur passes. */ void ApplyRadialBlurPasses( FRHICommandListImmediate& RHICmdList, const FViewInfo& View, const FLightSceneInfo* const LightSceneInfo, /** First pass source - this will not be overwritten. */ TRefCountPtr<IPooledRenderTarget>& FirstPassSource, /** Subsequent pass source, will also contain the final result. */ TRefCountPtr<IPooledRenderTarget>& LightShaftsSource, /** First pass dest. */ TRefCountPtr<IPooledRenderTarget>& LightShaftsDest) { TShaderMapRef<FScreenVS> ScreenVertexShader(View.ShaderMap); const FIntPoint BufferSize = FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(); const uint32 DownsampleFactor = GetLightShaftDownsampleFactor(); const FIntPoint FilterBufferSize = BufferSize / DownsampleFactor; const FIntPoint DownSampledXY = View.ViewRect.Min / DownsampleFactor; const uint32 DownsampledSizeX = View.ViewRect.Width() / DownsampleFactor; const uint32 DownsampledSizeY = View.ViewRect.Height() / DownsampleFactor; const uint32 NumPasses = FMath::Max(GLightShaftBlurPasses, 0); for (uint32 PassIndex = 0; PassIndex < NumPasses; PassIndex++) { SetRenderTarget(RHICmdList, LightShaftsDest->GetRenderTargetItem().TargetableTexture, FTextureRHIRef()); RHICmdList.SetViewport(0, 0, 0.0f, FilterBufferSize.X, FilterBufferSize.Y, 1.0f); RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); TShaderMapRef<FBlurLightShaftsPixelShader> BlurLightShaftsPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BlurLightShaftsBoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *ScreenVertexShader, *BlurLightShaftsPixelShader); TRefCountPtr<IPooledRenderTarget>& EffectiveSource = PassIndex == 0 ? FirstPassSource : LightShaftsSource; /// ? BlurLightShaftsPixelShader->SetParameters(RHICmdList, LightSceneInfo, View, PassIndex, EffectiveSource); { // Apply a radial blur to the bloom and occlusion mask DrawRectangle( RHICmdList, DownSampledXY.X, DownSampledXY.Y, DownsampledSizeX, DownsampledSizeY, DownSampledXY.X, DownSampledXY.Y, DownsampledSizeX, DownsampledSizeY, FilterBufferSize, FilterBufferSize, *ScreenVertexShader, EDRF_UseTriangleOptimization); } RHICmdList.CopyToResolveTarget(LightShaftsDest->GetRenderTargetItem().TargetableTexture, LightShaftsDest->GetRenderTargetItem().ShaderResourceTexture, false, FResolveParams()); // Swap input and output for the next pass Swap(LightShaftsSource, LightShaftsDest); } }
void DownsamplePass(FRHICommandListImmediate& RHICmdList, const FViewInfo& View, const FLightSceneInfo* LightSceneInfo, TRefCountPtr<IPooledRenderTarget>& LightShaftsSource, TRefCountPtr<IPooledRenderTarget>& LightShaftsDest) { const FIntPoint BufferSize = FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(); const uint32 DownsampleFactor = GetLightShaftDownsampleFactor(); const FIntPoint FilterBufferSize = BufferSize / DownsampleFactor; const FIntPoint DownSampledXY = View.ViewRect.Min / DownsampleFactor; const uint32 DownsampledSizeX = View.ViewRect.Width() / DownsampleFactor; const uint32 DownsampledSizeY = View.ViewRect.Height() / DownsampleFactor; SetRenderTarget(RHICmdList, LightShaftsDest->GetRenderTargetItem().TargetableTexture, FTextureRHIRef()); RHICmdList.SetViewport(DownSampledXY.X, DownSampledXY.Y, 0.0f, DownSampledXY.X + DownsampledSizeX, DownSampledXY.Y + DownsampledSizeY, 1.0f); // Set shaders and texture TShaderMapRef<FDownsampleLightShaftsVertexShader> DownsampleLightShaftsVertexShader(View.ShaderMap); TRefCountPtr<IPooledRenderTarget> UnusedRT; switch(LightSceneInfo->Proxy->GetLightType()) { case LightType_Directional: { TShaderMapRef<TDownsampleLightShaftsPixelShader<LightType_Directional, bDownsampleOcclusion> > DownsampleLightShaftsPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), DownsampleDirectionalLightShaftsBoundShaderState[bDownsampleOcclusion], GFilterVertexDeclaration.VertexDeclarationRHI, *DownsampleLightShaftsVertexShader, *DownsampleLightShaftsPixelShader); DownsampleLightShaftsPixelShader->SetParameters(RHICmdList, LightSceneInfo, View, UnusedRT); } break; case LightType_Spot: { TShaderMapRef<TDownsampleLightShaftsPixelShader<LightType_Spot, bDownsampleOcclusion> > DownsampleLightShaftsPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), DownsampleSpotLightShaftsBoundShaderState[bDownsampleOcclusion], GFilterVertexDeclaration.VertexDeclarationRHI, *DownsampleLightShaftsVertexShader, *DownsampleLightShaftsPixelShader); DownsampleLightShaftsPixelShader->SetParameters(RHICmdList, LightSceneInfo, View, UnusedRT); } break; default: case LightType_Point: { TShaderMapRef<TDownsampleLightShaftsPixelShader<LightType_Point, bDownsampleOcclusion> > DownsampleLightShaftsPixelShader(View.ShaderMap); SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), DownsamplePointLightShaftsBoundShaderState[bDownsampleOcclusion], GFilterVertexDeclaration.VertexDeclarationRHI, *DownsampleLightShaftsVertexShader, *DownsampleLightShaftsPixelShader); DownsampleLightShaftsPixelShader->SetParameters(RHICmdList, LightSceneInfo, View, UnusedRT); } break; } DownsampleLightShaftsVertexShader->SetParameters(RHICmdList, View); // No depth tests, no backface culling. RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI()); RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI()); RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI()); // Downsample scene color and depth, and convert them into a bloom term and an occlusion masking term DrawRectangle( RHICmdList, 0, 0, DownsampledSizeX, DownsampledSizeY, View.ViewRect.Min.X, View.ViewRect.Min.Y, View.ViewRect.Width(), View.ViewRect.Height(), FIntPoint(DownsampledSizeX, DownsampledSizeY), BufferSize, *DownsampleLightShaftsVertexShader, EDRF_UseTriangleOptimization); RHICmdList.CopyToResolveTarget(LightShaftsDest->GetRenderTargetItem().TargetableTexture, LightShaftsDest->GetRenderTargetItem().ShaderResourceTexture, false, FResolveParams()); Swap(LightShaftsSource, LightShaftsDest); }
void FRCPassPostProcessVisualizeBuffer::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(VisualizeBuffer, DEC_SCENE_ITEMS); const FPooledRenderTargetDesc* InputDesc = GetInputDesc(ePId_Input0); if(!InputDesc) { // input is not hooked up correctly return; } const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntRect SrcRect = View.ViewRect; FIntRect DestRect = View.ViewRect; FIntPoint SrcSize = InputDesc->Extent; const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context); // Set the view family's render target/viewport. RHISetRenderTarget(DestRenderTarget.TargetableTexture, FTextureRHIRef()); Context.SetViewportAndCallRHI(DestRect); // set the state RHISetBlendState(TStaticBlendState<>::GetRHI()); RHISetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI()); SetShaderTempl<false>(Context); // Draw a quad mapping scene color to the view's render target DrawRectangle( 0, 0, DestRect.Width(), DestRect.Height(), SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestRect.Size(), SrcSize, EDRF_UseTriangleOptimization); // Now draw the requested tiles into the grid TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); TShaderMapRef<FPostProcessVisualizeBufferPS<true> > PixelShader(GetGlobalShaderMap()); RHISetBlendState(TStaticBlendState<CW_RGB, BO_Add, BF_SourceAlpha, BF_InverseSourceAlpha>::GetRHI()); static FGlobalBoundShaderState BoundShaderState; SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); PixelShader->SetPS(Context); // Track the name and position of each tile we draw so we can write text labels over them struct LabelRecord { FString Label; int32 LocationX; int32 LocationY; }; TArray<LabelRecord> Labels; const int32 MaxTilesX = 4; const int32 MaxTilesY = 4; const int32 TileWidth = DestRect.Width() / MaxTilesX; const int32 TileHeight = DestRect.Height() / MaxTilesY; int32 CurrentTileIndex = 0; for (TArray<TileData>::TConstIterator It = Tiles.CreateConstIterator(); It; ++It, ++CurrentTileIndex) { FRenderingCompositeOutputRef Tile = It->Source; if (Tile.IsValid()) { FTextureRHIRef Texture = Tile.GetOutput()->PooledRenderTarget->GetRenderTargetItem().TargetableTexture; int32 TileX = CurrentTileIndex % MaxTilesX; int32 TileY = CurrentTileIndex / MaxTilesX; PixelShader->SetSourceTexture(Texture); DrawRectangle( TileX * TileWidth, TileY * TileHeight, TileWidth, TileHeight, SrcRect.Min.X, SrcRect.Min.Y, SrcRect.Width(), SrcRect.Height(), DestRect.Size(), SrcSize, EDRF_Default); Labels.Add(LabelRecord()); Labels.Last().Label = It->Name; Labels.Last().LocationX = 8 + TileX * TileWidth; Labels.Last().LocationY = (TileY + 1) * TileHeight - 19; } } // Draw tile labels // this is a helper class for FCanvas to be able to get screen size class FRenderTargetTemp : public FRenderTarget { public: const FSceneView& View; const FTexture2DRHIRef Texture; FRenderTargetTemp(const FSceneView& InView, const FTexture2DRHIRef InTexture) : View(InView), Texture(InTexture) { } virtual FIntPoint GetSizeXY() const { return View.ViewRect.Size(); }; virtual const FTexture2DRHIRef& GetRenderTargetTexture() const { return Texture; } } TempRenderTarget(View, (const FTexture2DRHIRef&)DestRenderTarget.TargetableTexture); FCanvas Canvas(&TempRenderTarget, NULL, ViewFamily.CurrentRealTime, ViewFamily.CurrentWorldTime, ViewFamily.DeltaWorldTime); FLinearColor LabelColor(1, 1, 0); for (auto It = Labels.CreateConstIterator(); It; ++It) { Canvas.DrawShadowedString(It->LocationX, It->LocationY, *It->Label, GetStatsFont(), LabelColor); } Canvas.Flush(); RHICopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams()); }