void FCompositionLighting::ProcessAfterBasePass(FRHICommandListImmediate& RHICmdList, FViewInfo& View) { check(IsInRenderingThread()); FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList); // might get renamed to refracted or ...WithAO SceneContext.GetSceneColor()->SetDebugName(TEXT("SceneColor")); // to be able to observe results with VisualizeTexture GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GetSceneColor()); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferA); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferB); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferC); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferD); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferE); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferVelocity); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ScreenSpaceAO); // so that the passes can register themselves to the graph { FMemMark Mark(FMemStack::Get()); FRenderingCompositePassContext CompositeContext(RHICmdList, View); FPostprocessContext Context(CompositeContext.Graph, View); // Add the passes we want to add to the graph (commenting a line means the pass is not inserted into the graph) ---------- // decals are before AmbientOcclusion so the decal can output a normal that AO is affected by if( Context.View.Family->EngineShowFlags.Decals && !Context.View.Family->EngineShowFlags.VisualizeLightCulling) // decal are distracting when looking at LightCulling { AddDeferredDecalsBeforeLighting(Context); } FRenderingCompositeOutputRef AmbientOcclusion; if(uint32 Levels = ComputeAmbientOcclusionPassCount(Context)) { AmbientOcclusion = AddPostProcessingAmbientOcclusion(RHICmdList, Context, Levels); } if(IsAmbientCubemapPassRequired(Context)) { AddPostProcessingAmbientCubemap(Context, AmbientOcclusion); } // The graph setup should be finished before this line ---------------------------------------- SCOPED_DRAW_EVENT(RHICmdList, LightCompositionTasks_PreLighting); TRefCountPtr<IPooledRenderTarget>& SceneColor = SceneContext.GetSceneColor(); Context.FinalOutput.GetOutput()->RenderTargetDesc = SceneColor->GetDesc(); Context.FinalOutput.GetOutput()->PooledRenderTarget = SceneColor; CompositeContext.Process(Context.FinalOutput.GetPass(), TEXT("CompositionLighting_AfterBasePass")); } }
bool ShouldRenderScreenSpaceAmbientOcclusion(const FViewInfo& View) { bool bEnabled = true; if (!IsLpvIndirectPassRequired(View)) { bEnabled = View.FinalPostProcessSettings.AmbientOcclusionIntensity > 0 && View.Family->EngineShowFlags.Lighting && View.FinalPostProcessSettings.AmbientOcclusionRadius >= 0.1f && !View.Family->UseDebugViewPS() && (FSSAOHelper::IsBasePassAmbientOcclusionRequired(View) || IsAmbientCubemapPassRequired(View) || IsReflectionEnvironmentActive(View) || IsSkylightActive(View) || View.Family->EngineShowFlags.VisualizeBuffer) && !IsAnyForwardShadingEnabled(View.GetShaderPlatform()); } return bEnabled; }
// @return 0:off, 0..4 static uint32 ComputeAmbientOcclusionPassCount(FPostprocessContext& Context) { uint32 Ret = 0; bool bEnabled = true; if(!IsLpvIndirectPassRequired(Context)) { bEnabled = Context.View.FinalPostProcessSettings.AmbientOcclusionIntensity > 0 && Context.View.FinalPostProcessSettings.AmbientOcclusionRadius >= 0.1f && (IsBasePassAmbientOcclusionRequired(Context) || IsAmbientCubemapPassRequired(Context) || IsReflectionEnvironmentActive(Context) || IsSkylightActive(Context) || Context.View.Family->EngineShowFlags.VisualizeBuffer ) && !IsSimpleDynamicLightingEnabled(); } if(bEnabled) { static const auto ICVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.AmbientOcclusionLevels")); Ret = FMath::Clamp(ICVar->GetValueOnRenderThread(), 0, 4); } return Ret; }
void FCompositionLighting::ProcessAfterBasePass(FRHICommandListImmediate& RHICmdList, FViewInfo& View) { check(IsInRenderingThread()); FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList); // might get renamed to refracted or ...WithAO SceneContext.GetSceneColor()->SetDebugName(TEXT("SceneColor")); // to be able to observe results with VisualizeTexture GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GetSceneColor()); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferA); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferB); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferC); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferD); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferE); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferVelocity); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ScreenSpaceAO); // so that the passes can register themselves to the graph { FMemMark Mark(FMemStack::Get()); FRenderingCompositePassContext CompositeContext(RHICmdList, View); FPostprocessContext Context(RHICmdList, CompositeContext.Graph, View); // Add the passes we want to add to the graph ---------- if( Context.View.Family->EngineShowFlags.Decals && !Context.View.Family->EngineShowFlags.ShaderComplexity) { // DRS_AfterBasePass is for Volumetric decals which don't support ShaderComplexity yet FRenderingCompositePass* Pass = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessDeferredDecals(DRS_AfterBasePass)); Pass->SetInput(ePId_Input0, Context.FinalOutput); Context.FinalOutput = FRenderingCompositeOutputRef(Pass); } // decals are before AmbientOcclusion so the decal can output a normal that AO is affected by if( Context.View.Family->EngineShowFlags.Decals && !Context.View.Family->EngineShowFlags.VisualizeLightCulling) // decal are distracting when looking at LightCulling { FRenderingCompositePass* Pass = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessDeferredDecals(DRS_BeforeLighting)); Pass->SetInput(ePId_Input0, Context.FinalOutput); Context.FinalOutput = FRenderingCompositeOutputRef(Pass); } FRenderingCompositeOutputRef AmbientOcclusion; uint32 SSAOLevels = ComputeAmbientOcclusionPassCount(Context.View); if (SSAOLevels) { if(!FSSAOHelper::IsAmbientOcclusionAsyncCompute(Context.View, SSAOLevels)) { AmbientOcclusion = AddPostProcessingAmbientOcclusion(RHICmdList, Context, SSAOLevels); } if (FSSAOHelper::IsBasePassAmbientOcclusionRequired(Context.View)) { FRenderingCompositePass* Pass = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessBasePassAO()); Pass->AddDependency(Context.FinalOutput); Context.FinalOutput = FRenderingCompositeOutputRef(Pass); } } if (IsAmbientCubemapPassRequired(Context.View)) { AddPostProcessingAmbientCubemap(Context, AmbientOcclusion); } // The graph setup should be finished before this line ---------------------------------------- SCOPED_DRAW_EVENT(RHICmdList, LightCompositionTasks_PreLighting); SCOPED_GPU_STAT(RHICmdList, Stat_GPU_CompositionPreLighting); TRefCountPtr<IPooledRenderTarget>& SceneColor = SceneContext.GetSceneColor(); Context.FinalOutput.GetOutput()->RenderTargetDesc = SceneColor->GetDesc(); Context.FinalOutput.GetOutput()->PooledRenderTarget = SceneColor; CompositeContext.Process(Context.FinalOutput.GetPass(), TEXT("CompositionLighting_AfterBasePass")); } }