/** * Initialize scene's views. * Check visibility, sort translucent items, etc. */ void FForwardShadingSceneRenderer::InitViews(FRHICommandListImmediate& RHICmdList) { SCOPED_DRAW_EVENT(RHICmdList, InitViews); SCOPE_CYCLE_COUNTER(STAT_InitViewsTime); FILCUpdatePrimTaskData ILCTaskData; PreVisibilityFrameSetup(RHICmdList); ComputeViewVisibility(RHICmdList); PostVisibilityFrameSetup(ILCTaskData); bool bDynamicShadows = ViewFamily.EngineShowFlags.DynamicShadows && GetShadowQuality() > 0; if (bDynamicShadows && !IsSimpleDynamicLightingEnabled()) { // Setup dynamic shadows. InitDynamicShadows(RHICmdList); } // if we kicked off ILC update via task, wait and finalize. if (ILCTaskData.TaskRef.IsValid()) { Scene->IndirectLightingCache.FinalizeCacheUpdates(Scene, *this, ILCTaskData); } // initialize per-view uniform buffer. Pass in shadow info as necessary. for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { const TArray<FProjectedShadowInfo*, SceneRenderingAllocator>* DirectionalLightShadowInfo = nullptr; FViewInfo& ViewInfo = Views[ViewIndex]; FScene* Scene = (FScene*)ViewInfo.Family->Scene; if (bDynamicShadows && Scene->SimpleDirectionalLight) { int32 LightId = Scene->SimpleDirectionalLight->Id; if (VisibleLightInfos.IsValidIndex(LightId)) { const FVisibleLightInfo& VisibleLightInfo = VisibleLightInfos[LightId]; if (VisibleLightInfo.AllProjectedShadows.Num() > 0) { DirectionalLightShadowInfo = &VisibleLightInfo.AllProjectedShadows; } } } // Initialize the view's RHI resources. Views[ViewIndex].InitRHIResources(DirectionalLightShadowInfo); } // Now that the indirect lighting cache is updated, we can update the primitive precomputed lighting buffers. UpdatePrimitivePrecomputedLightingBuffers(); OnStartFrame(); }
/** * Initialize scene's views. * Check visibility, sort translucent items, etc. */ void FForwardShadingSceneRenderer::InitViews(FRHICommandListImmediate& RHICmdList) { SCOPED_DRAW_EVENT(RHICmdList, InitViews); SCOPE_CYCLE_COUNTER(STAT_InitViewsTime); PreVisibilityFrameSetup(RHICmdList); ComputeViewVisibility(RHICmdList); PostVisibilityFrameSetup(); bool bDynamicShadows = ViewFamily.EngineShowFlags.DynamicShadows && GetShadowQuality() > 0; if (bDynamicShadows && !IsSimpleDynamicLightingEnabled()) { // Setup dynamic shadows. InitDynamicShadows(RHICmdList); } // initialize per-view uniform buffer. Pass in shadow info as necessary. for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { const TArray<FProjectedShadowInfo*, SceneRenderingAllocator>* DirectionalLightShadowInfo = nullptr; FViewInfo& ViewInfo = Views[ViewIndex]; FScene* Scene = (FScene*)ViewInfo.Family->Scene; if (bDynamicShadows && Scene->SimpleDirectionalLight) { int32 LightId = Scene->SimpleDirectionalLight->Id; if (VisibleLightInfos.IsValidIndex(LightId)) { const FVisibleLightInfo& VisibleLightInfo = VisibleLightInfos[LightId]; if (VisibleLightInfo.AllProjectedShadows.Num() > 0) { DirectionalLightShadowInfo = &VisibleLightInfo.AllProjectedShadows; } } } // Initialize the view's RHI resources. Views[ViewIndex].InitRHIResources(DirectionalLightShadowInfo); } OnStartFrame(); }
// @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; }
static bool IsBasePassAmbientOcclusionRequired(FPostprocessContext& Context) { // the BaseAO pass is only worth with some AO return Context.View.FinalPostProcessSettings.AmbientOcclusionStaticFraction >= 1 / 100.0f && !IsSimpleDynamicLightingEnabled(); }
static bool IsReflectionEnvironmentActive(FPostprocessContext& Context) { FScene* Scene = (FScene*)Context.View.Family->Scene; // LPV & Screenspace Reflections : Reflection Environment active if either LPV (assumed true if this was called), Reflection Captures or SSR active bool IsReflectingEnvironment = Context.View.Family->EngineShowFlags.ReflectionEnvironment; bool HasReflectionCaptures = (Scene->ReflectionSceneData.RegisteredReflectionCaptures.Num() > 0); bool HasSSR = Context.View.Family->EngineShowFlags.ScreenSpaceReflections; return (Scene->GetFeatureLevel() == ERHIFeatureLevel::SM5 && IsReflectingEnvironment && (HasReflectionCaptures || HasSSR) && !IsSimpleDynamicLightingEnabled()); }
static bool IsAmbientCubemapPassRequired(FPostprocessContext& Context) { FScene* Scene = (FScene*)Context.View.Family->Scene; return Context.View.FinalPostProcessSettings.ContributingCubemaps.Num() != 0 && !IsSimpleDynamicLightingEnabled(); }
void FCompositionLighting::ProcessAfterLighting(FRHICommandListImmediate& RHICmdList, FViewInfo& View) { check(IsInRenderingThread()); FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ReflectiveShadowMapDiffuse); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ReflectiveShadowMapNormal); GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ReflectiveShadowMapDepth); { FMemMark Mark(FMemStack::Get()); FRenderingCompositePassContext CompositeContext(RHICmdList, View); FPostprocessContext Context(CompositeContext.Graph, View); FRenderingCompositeOutputRef AmbientOcclusion; // Screen Space Subsurface Scattering { float Radius = CVarSSSScale.GetValueOnRenderThread(); bool bSimpleDynamicLighting = IsSimpleDynamicLightingEnabled(); bool bScreenSpaceSubsurfacePassNeeded = (View.ShadingModelMaskInView & (1 << MSM_SubsurfaceProfile)) != 0; if (bScreenSpaceSubsurfacePassNeeded && Radius > 0 && !bSimpleDynamicLighting && View.Family->EngineShowFlags.SubsurfaceScattering && //@todo-rco: Remove this when we fix the cross-compiler !IsOpenGLPlatform(View.GetShaderPlatform())) { // can be optimized out if we don't do split screen/stereo rendering (should be done after we some post process refactoring) FRenderingCompositePass* PassExtractSpecular = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceExtractSpecular()); PassExtractSpecular->SetInput(ePId_Input0, Context.FinalOutput); FRenderingCompositePass* PassSetup = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceSetup(View)); PassSetup->SetInput(ePId_Input0, Context.FinalOutput); FRenderingCompositePass* Pass0 = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurface(0)); Pass0->SetInput(ePId_Input0, PassSetup); FRenderingCompositePass* Pass1 = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurface(1)); Pass1->SetInput(ePId_Input0, Pass0); Pass1->SetInput(ePId_Input1, PassSetup); // full res composite pass, no blurring (Radius=0) FRenderingCompositePass* RecombinePass = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceRecombine()); RecombinePass->SetInput(ePId_Input0, Pass1); RecombinePass->SetInput(ePId_Input1, PassExtractSpecular); SCOPED_DRAW_EVENT(RHICmdList, CompositionLighting_SSSSS); CompositeContext.Process(RecombinePass, TEXT("CompositionLighting_SSSSS")); } } // The graph setup should be finished before this line ---------------------------------------- SCOPED_DRAW_EVENT(RHICmdList, CompositionAfterLighting); // we don't replace the final element with the scenecolor because this is what those passes should do by themself CompositeContext.Process(Context.FinalOutput.GetPass(), TEXT("CompositionLighting")); } // We only release the after the last view was processed (SplitScreen) if(View.Family->Views[View.Family->Views.Num() - 1] == &View) { // The RT should be released as early as possible to allow sharing of that memory for other purposes. // This becomes even more important with some limited VRam (XBoxOne). SceneContext.SetLightAttenuation(0); } }