void FRCPassPostProcessLpvIndirect::Process(FRenderingCompositePassContext& Context) { SCOPED_DRAW_EVENT(PostProcessLpvIndirect, DEC_SCENE_ITEMS); const FPostProcessSettings& PostprocessSettings = Context.View.FinalPostProcessSettings; const FSceneView& View = Context.View; const FSceneViewFamily& ViewFamily = *(View.Family); FIntRect SrcRect = View.ViewRect; // todo: view size should scale with input texture size so we can do SSAO in half resolution as well FIntRect DestRect = View.ViewRect; FIntPoint DestSize = DestRect.Size(); uint32 NumReflectionCaptures = ViewFamily.Scene->GetRenderScene()->ReflectionSceneData.RegisteredReflectionCaptures.Num(); const FSceneRenderTargetItem& DestColorRenderTarget = GSceneRenderTargets.SceneColor->GetRenderTargetItem(); // Set the view family's render target/viewport. FTextureRHIParamRef RenderTargets[] = { DestColorRenderTarget.TargetableTexture, }; // Set the view family's render target/viewport. RHISetRenderTargets(1, RenderTargets, GSceneRenderTargets.GetSceneDepthSurface(), 0, NULL); Context.SetViewportAndCallRHI(View.ViewRect); // set the state if ( ViewFamily.EngineShowFlags.LpvLightingOnly ) { RHISetBlendState( TStaticBlendState<>::GetRHI() ); } else { // additive blending RHISetBlendState(TStaticBlendState<CW_RGB,BO_Add,BF_One,BF_One>::GetRHI()); } RHISetRasterizerState(TStaticRasterizerState<>::GetRHI()); RHISetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI()); TShaderMapRef<FPostProcessVS> VertexShader(GetGlobalShaderMap()); FSceneViewState* ViewState = (FSceneViewState*)View.State; FLightPropagationVolume* Lpv = NULL; bool bUseLpv = false; if ( ViewState ) { Lpv = ViewState->GetLightPropagationVolume(); bUseLpv = Lpv && PostprocessSettings.LPVIntensity > 0.0f; } if ( !bUseLpv ) { return; } TShaderMapRef<FPostProcessLpvIndirectPS> PixelShader(GetGlobalShaderMap()); static FGlobalBoundShaderState BoundShaderState; // call it once after setting up the shader data to avoid the warnings in the function SetGlobalBoundShaderState(BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader); FLpvReadUniformBufferParameters LpvReadUniformBufferParams; FLpvReadUniformBufferRef LpvReadUniformBuffer; LpvReadUniformBufferParams = Lpv->GetReadUniformBufferParams(); LpvReadUniformBuffer = FLpvReadUniformBufferRef::CreateUniformBufferImmediate( LpvReadUniformBufferParams, UniformBuffer_SingleUse ); #if LPV_VOLUME_TEXTURE FTextureRHIParamRef LpvBufferSrvs[7]; for ( int i = 0; i < 7; i++ ) { LpvBufferSrvs[i] = Lpv->GetLpvBufferSrv(i); } PixelShader->SetParameters(LpvBufferSrvs, LpvReadUniformBuffer, Context ); #else FShaderResourceViewRHIParamRef LpvBufferSrv = Lpv->GetLpvBufferSrv(); PixelShader->SetParameters(LpvBufferSrv, LpvReadUniformBuffer, Context ); #endif // Draw a quad mapping scene color to the view's render target DrawRectangle( 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(), GSceneRenderTargets.SceneColor->GetDesc().Extent); RHICopyToResolveTarget(DestColorRenderTarget.TargetableTexture, DestColorRenderTarget.ShaderResourceTexture, false, FResolveParams()); }
void FRCPassPostProcessLpvIndirect::Process(FRenderingCompositePassContext& Context) { FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(Context.RHICmdList); { FRenderingCompositeOutput* OutputOfMyInput = GetInput(ePId_Input0)->GetOutput(); PassOutputs[0].PooledRenderTarget = OutputOfMyInput->PooledRenderTarget; OutputOfMyInput->RenderTargetDesc.DebugName = PassOutputs[0].RenderTargetDesc.DebugName; PassOutputs[0].RenderTargetDesc = OutputOfMyInput->RenderTargetDesc; check(PassOutputs[0].RenderTargetDesc.Extent.X); check(PassOutputs[0].RenderTargetDesc.Extent.Y); } const FFinalPostProcessSettings& PostprocessSettings = Context.View.FinalPostProcessSettings; const FSceneView& View = Context.View; FSceneViewState* ViewState = (FSceneViewState*)View.State; if(!ViewState) { return; } // This check should be inclusive to stereo views const bool bIncludeStereoViews = true; FLightPropagationVolume* Lpv = ViewState->GetLightPropagationVolume(Context.GetFeatureLevel(), bIncludeStereoViews); const FLightPropagationVolumeSettings& LPVSettings = PostprocessSettings.BlendableManager.GetSingleFinalDataConst<FLightPropagationVolumeSettings>(); if(!Lpv || LPVSettings.LPVIntensity == 0.0f) { return; } const FSceneViewFamily& ViewFamily = *(View.Family); FIntRect SrcRect = View.ViewRect; // todo: view size should scale with input texture size so we can do SSAO in half resolution as well FIntRect DestRect = View.ViewRect; FIntPoint DestSize = DestRect.Size(); const bool bMixing = CVarLPVMixing.GetValueOnRenderThread() != 0; // Apply specular separately if we're mixing reflection environment with indirect lighting const bool bApplySeparateSpecularRT = View.Family->EngineShowFlags.ReflectionEnvironment && bMixing; const FSceneRenderTargetItem& DestColorRenderTarget = SceneContext.GetSceneColor()->GetRenderTargetItem(); const FSceneRenderTargetItem& DestSpecularRenderTarget = SceneContext.LightAccumulation->GetRenderTargetItem(); const FSceneRenderTargetItem& DestDirectionalOcclusionRenderTarget = SceneContext.DirectionalOcclusion->GetRenderTargetItem(); // Make sure the LPV Update has completed Lpv->InsertGPUWaitForAsyncUpdate(Context.RHICmdList); if ( LPVSettings.LPVDirectionalOcclusionIntensity > 0.0001f ) { DoDirectionalOcclusionPass(Context); } FTextureRHIParamRef RenderTargets[2]; RenderTargets[0] = DestColorRenderTarget.TargetableTexture; RenderTargets[1] = DestSpecularRenderTarget.TargetableTexture; // Set the view family's render target/viewport. // If specular not applied: set only color target uint32 NumRenderTargets = 1; if ( bApplySeparateSpecularRT ) { NumRenderTargets = 2; } SetRenderTargets(Context.RHICmdList, NumRenderTargets, RenderTargets, 0, ESimpleRenderTargetMode::EExistingColorAndDepth, FExclusiveDepthStencil::DepthRead_StencilNop); Context.SetViewportAndCallRHI(View.ViewRect); // set the state Context.RHICmdList.SetBlendState(TStaticBlendState<CW_RGB,BO_Add,BF_One,BF_One,BO_Add,BF_One,BF_One>::GetRHI()); Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI()); Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false,CF_Always>::GetRHI()); TShaderMapRef<FPostProcessVS> VertexShader(Context.GetShaderMap()); TShaderMapRef< TPostProcessLpvIndirectPS<false> > PixelShaderNoSpecular(Context.GetShaderMap()); TShaderMapRef< TPostProcessLpvIndirectPS<true> > PixelShaderWithSpecular(Context.GetShaderMap()); FPostProcessLpvIndirectPS* PixelShader = NULL; int BoundShaderIndex = -1; if ( bApplySeparateSpecularRT ) { PixelShader = (FPostProcessLpvIndirectPS*)*PixelShaderWithSpecular; BoundShaderIndex = 0; } else { PixelShader = (FPostProcessLpvIndirectPS*)*PixelShaderNoSpecular; BoundShaderIndex = 1; } static FGlobalBoundShaderState BoundShaderState[2]; // call it once after setting up the shader data to avoid the warnings in the function SetGlobalBoundShaderState(Context.RHICmdList, Context.GetFeatureLevel(), BoundShaderState[BoundShaderIndex], GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, PixelShader); FLpvReadUniformBufferParameters LpvReadUniformBufferParams; FLpvReadUniformBufferRef LpvReadUniformBuffer; LpvReadUniformBufferParams = Lpv->GetReadUniformBufferParams(); LpvReadUniformBuffer = FLpvReadUniformBufferRef::CreateUniformBufferImmediate( LpvReadUniformBufferParams, UniformBuffer_SingleDraw ); FTextureRHIParamRef LpvBufferSrvs[7]; for ( int i = 0; i < 7; i++ ) { LpvBufferSrvs[i] = Lpv->GetLpvBufferSrv(i); } PixelShader->SetParameters( LpvBufferSrvs, Lpv->GetAOVolumeTextureSRV(), LpvReadUniformBuffer, Context ); { SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessLpvIndirect ); DrawPostProcessPass( 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(), SceneContext.GetBufferSizeXY(), *VertexShader, View.StereoPass, Context.HasHmdMesh()); Context.RHICmdList.CopyToResolveTarget(DestColorRenderTarget.TargetableTexture, DestColorRenderTarget.ShaderResourceTexture, false, FResolveParams()); if(bApplySeparateSpecularRT) { Context.RHICmdList.CopyToResolveTarget(DestSpecularRenderTarget.TargetableTexture, DestSpecularRenderTarget.ShaderResourceTexture, false, FResolveParams()); } } if ( LPVSettings.LPVDirectionalOcclusionIntensity > 0.0001f ) { GRenderTargetPool.VisualizeTexture.SetCheckPoint(Context.RHICmdList, SceneContext.DirectionalOcclusion); } }