r.FastVRam.ScreenSpaceAO

r.FastVRam.ScreenSpaceAO

#Overview

name: r.FastVRam.ScreenSpaceAO

This variable is created as a Console Variable (cvar).

It is referenced in 33 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.FastVRam.ScreenSpaceAO is to control the texture creation flags for the Screen Space Ambient Occlusion (SSAO) texture in Unreal Engine 5’s rendering system. This setting variable is part of the fast VRAM configuration system, which allows developers to optimize memory usage and performance for various render targets.

Key points about r.FastVRam.ScreenSpaceAO:

  1. It’s used by the rendering system, specifically for the SSAO pass.

  2. The Unreal Engine renderer subsystem relies on this setting variable.

  3. The value is set through a console variable (CVar) system, as seen in the FASTVRAM_CVAR macro usage.

  4. It interacts with the FFastVramConfig struct, which contains flags for various render targets.

  5. Developers should be aware that changing this variable can affect performance and memory usage related to SSAO.

  6. Best practices include carefully considering the trade-offs between fast VRAM usage and render quality when adjusting this setting.

The associated variable ScreenSpaceAO is used throughout the rendering pipeline:

  1. It’s referenced in creating and accessing the SSAO texture in the FSceneTextures struct.

  2. It’s used in various rendering passes, such as the base pass and forward shading.

  3. The variable is checked in multiple places to determine if SSAO has been produced and should be used in subsequent rendering steps.

  4. It’s part of the SceneTextureParameters, which are used in many shaders and rendering functions.

When using these variables, developers should:

  1. Consider the impact on performance and memory usage when enabling or disabling fast VRAM for SSAO.

  2. Ensure that SSAO is properly set up and produced before attempting to use it in later rendering stages.

  3. Be aware of the interactions between SSAO and other rendering features, such as deferred shading and forward rendering paths.

  4. Profile the application to determine the optimal settings for their specific use case, as the impact may vary depending on the hardware and scene complexity.

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneRendering.cpp:493

Scope: file

Source code excerpt:

FASTVRAM_CVAR(SeparateTranslucency, 0); 
FASTVRAM_CVAR(SeparateTranslucencyModulate, 0);
FASTVRAM_CVAR(ScreenSpaceAO,0);
FASTVRAM_CVAR(SSR, 0);
FASTVRAM_CVAR(DBufferA, 0);
FASTVRAM_CVAR(DBufferB, 0);
FASTVRAM_CVAR(DBufferC, 0); 
FASTVRAM_CVAR(DBufferMask, 0);
FASTVRAM_CVAR(DOFSetup, 1);

#Associated Variable and Callsites

This variable is associated with another variable named ScreenSpaceAO. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Plugins/Compositing/Composure/Source/Composure/Private/ComposureUtils.cpp:8

Scope (from outer to inner):

file
function     void FComposureUtils::SetEngineShowFlagsForPostprocessingOnly

Source code excerpt:

void FComposureUtils::SetEngineShowFlagsForPostprocessingOnly(FEngineShowFlags& EngineShowFlags)
{
	EngineShowFlags.DynamicShadows = false;
	EngineShowFlags.ReflectionEnvironment = false;
	EngineShowFlags.ScreenSpaceReflections = false;
	EngineShowFlags.ScreenSpaceAO = false;
	EngineShowFlags.LightShafts = false;
	EngineShowFlags.Lighting = false;
	EngineShowFlags.DeferredLighting = false;
	EngineShowFlags.Decals = false;
	EngineShowFlags.Translucency = false;
	EngineShowFlags.AntiAliasing = false;
	EngineShowFlags.MotionBlur = false;
	EngineShowFlags.Bloom = false;
	EngineShowFlags.EyeAdaptation = false;
	EngineShowFlags.VolumetricFog = false;
	EngineShowFlags.Atmosphere = false;

#Loc: <Workspace>/Engine/Source/Developer/FunctionalTesting/Private/AutomationBlueprintFunctionLibrary.cpp:185

Scope (from outer to inner):

file
class        class FAutomationViewExtension : public FWorldSceneViewExtension
function     virtual void SetupViewFamily

Source code excerpt:

			FEngineShowFlags& ShowFlags = InViewFamily.EngineShowFlags;
			ShowFlags.SetAntiAliasing(ViewSettings->AntiAliasing);
			ShowFlags.SetMotionBlur(ViewSettings->MotionBlur);
			ShowFlags.SetTemporalAA(ViewSettings->TemporalAA);
			ShowFlags.SetScreenSpaceReflections(ViewSettings->ScreenSpaceReflections);
			ShowFlags.SetScreenSpaceAO(ViewSettings->ScreenSpaceAO);
			ShowFlags.SetDistanceFieldAO(ViewSettings->DistanceFieldAO);
			ShowFlags.SetContactShadows(ViewSettings->ContactShadows);
			ShowFlags.SetEyeAdaptation(ViewSettings->EyeAdaptation);
			ShowFlags.SetBloom(ViewSettings->Bloom);
		}

		if (Options.bOverride_OverrideTimeTo)
		{
			// Turn off time the ultimate source of noise.
			InViewFamily.Time = FGameTime::CreateUndilated(Options.OverrideTimeTo, 0.0f);
		}

#Loc: <Workspace>/Engine/Source/Developer/FunctionalTesting/Public/AutomationViewSettings.h:16

Scope (from outer to inner):

file
class        class UAutomationViewSettings : public UDataAsset
function     UAutomationViewSettings

Source code excerpt:

	UAutomationViewSettings()
		: AntiAliasing(true)
		, MotionBlur(true)
		, TemporalAA(true)
		, ScreenSpaceReflections(true)
		, ScreenSpaceAO(true)
		, DistanceFieldAO(true)
		, ContactShadows(true)
		, EyeAdaptation(true)
		, Bloom(true)
	{
	}

	UPROPERTY(EditAnywhere, Category="Rendering")
	bool AntiAliasing;
	
	UPROPERTY(EditAnywhere, Category="Rendering")

#Loc: <Workspace>/Engine/Source/Developer/FunctionalTesting/Public/AutomationViewSettings.h:37

Scope (from outer to inner):

file
class        class UAutomationViewSettings : public UDataAsset

Source code excerpt:

	
	UPROPERTY(EditAnywhere, Category="Rendering")
	bool ScreenSpaceReflections;
	
	UPROPERTY(EditAnywhere, Category="Rendering")
	bool ScreenSpaceAO;
	
	UPROPERTY(EditAnywhere, Category="Rendering")
	bool DistanceFieldAO;
	
	UPROPERTY(EditAnywhere, Category="Rendering")
	bool ContactShadows;
	
	UPROPERTY(EditAnywhere, Category="Rendering")
	bool EyeAdaptation;

	UPROPERTY(EditAnywhere, Category = "Rendering")

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/SceneView.cpp:2198

Scope (from outer to inner):

file
function     void FSceneView::EndFinalPostprocessSettings

Source code excerpt:

		{
			FinalPostProcessSettings.AmbientOcclusionStaticFraction = Value;
		}
	}

	if(!Family->EngineShowFlags.AmbientOcclusion || !Family->EngineShowFlags.ScreenSpaceAO)
	{
		FinalPostProcessSettings.AmbientOcclusionIntensity = 0;
	}

	{
		static const auto AmbientOcclusionRadiusScaleCVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.AmbientOcclusionRadiusScale"));

		float Scale = FMath::Clamp(AmbientOcclusionRadiusScaleCVar->GetValueOnGameThread(), 0.1f, 15.0f);

		FinalPostProcessSettings.AmbientOcclusionRadius *= Scale;
	}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/ShowFlagsValues.inl:340

Scope: file

Source code excerpt:

/** Global Distance field */
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeGlobalDistanceField, SFG_Visualize, NSLOCTEXT("UnrealEd", "GlobalDistanceFieldSF", "Global DistanceField"))
/** Enable the debug visualization of diffuse/specular lighting (direct and indirect) using probes */
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeLightingOnProbes, SFG_Visualize, NSLOCTEXT("UnrealEd", "VisualizeLightingOnProbesSF", "Visualize Lighting on Probes"))
/** Screen space AO, for now SHOWFLAG_ALWAYS_ACCESSIBLE because r.GBuffer need that */
SHOWFLAG_ALWAYS_ACCESSIBLE(ScreenSpaceAO, SFG_LightingFeatures, NSLOCTEXT("UnrealEd", "ScreenSpaceAOSF", "Screen Space Ambient Occlusion"))
/** Distance field AO, for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */
SHOWFLAG_ALWAYS_ACCESSIBLE(DistanceFieldAO, SFG_LightingFeatures, NSLOCTEXT("UnrealEd", "DistanceFieldAOSF", "Distance Field Ambient Occlusion"))
/** Lumen GI */
SHOWFLAG_ALWAYS_ACCESSIBLE(LumenGlobalIllumination, SFG_LightingFeatures, NSLOCTEXT("UnrealEd", "LumenGlobalIlluminationSF", "Lumen Global Illumination"))
/** SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */
SHOWFLAG_ALWAYS_ACCESSIBLE(VolumetricFog, SFG_LightingFeatures, NSLOCTEXT("UnrealEd", "VolumetricFogSF", "Volumetric Fog"))
/** Visualize screen space reflections, for developer (by default off): */
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeSSR, SFG_Visualize, NSLOCTEXT("UnrealEd", "VisualizeSSR", "Screen Space Reflections"))
/** Visualize the Shading Models, mostly or debugging and profiling */
SHOWFLAG_FIXED_IN_SHIPPING(0, VisualizeShadingModels, SFG_Visualize, NSLOCTEXT("UnrealEd", "VisualizeShadingModels", "Shading Models"))
/** Visualize the senses configuration of AIs' PawnSensingComponent */

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Internal/SceneTextures.h:85

Scope: file

Source code excerpt:

	// (Mobile Local Light Prepass) Textures containing LocalLight Direction and Color
	FRDGTextureRef MobileLocalLightTextureA {};
	FRDGTextureRef MobileLocalLightTextureB {};

	// Texture containing the screen space ambient occlusion result.
	FRDGTextureRef ScreenSpaceAO{};

	// Texture used by the quad overdraw debug view mode when enabled.
	FRDGTextureRef QuadOverdraw{};

	// (Mobile) Texture used by mobile PPR in the next frame.
	FRDGTextureRef PixelProjectedReflection{};

	// Textures used to composite editor primitives. Also used by the base pass when in wireframe mode.
#if WITH_EDITOR
	FRDGTextureRef EditorPrimitiveColor{};
	FRDGTextureRef EditorPrimitiveDepth{};

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/BasePassRendering.cpp:780

Scope (from outer to inner):

file
function     TRDGUniformBufferRef<FOpaqueBasePassUniformParameters> CreateOpaqueBasePassUniformBuffer

Source code excerpt:

		{
			BasePassParameters.UseForwardScreenSpaceShadowMask = 1;
			BasePassParameters.ForwardScreenSpaceShadowMaskTexture = ForwardBasePassTextures.ScreenSpaceShadowMask;
		}

		if (HasBeenProduced(ForwardBasePassTextures.ScreenSpaceAO))
		{
			BasePassParameters.IndirectOcclusionTexture = ForwardBasePassTextures.ScreenSpaceAO;
		}

		if (ForwardBasePassTextures.SceneDepthIfResolved)
		{
			BasePassParameters.ResolvedSceneDepthTexture = ForwardBasePassTextures.SceneDepthIfResolved;
		}
		BasePassParameters.Is24BitUnormDepthStencil = ForwardBasePassTextures.bIs24BitUnormDepthStencil ? 1 : 0;
	}

	// DBuffer Decals
	BasePassParameters.DBuffer = GetDBufferParameters(GraphBuilder, DBufferTextures, View.GetShaderPlatform());

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/BasePassRendering.cpp:1153

Scope (from outer to inner):

file
function     void FDeferredShadingSceneRenderer::RenderBasePass

Source code excerpt:

	FForwardBasePassTextures ForwardBasePassTextures{};

	if (bForwardShadingEnabled)
	{
		ForwardBasePassTextures.SceneDepthIfResolved = SceneTextures.Depth.IsSeparate() ? SceneTextures.Depth.Resolve : nullptr;
		ForwardBasePassTextures.ScreenSpaceAO = SceneTextures.ScreenSpaceAO;
		ForwardBasePassTextures.ScreenSpaceShadowMask = ForwardShadowMaskTexture;
	}
	else if (!ExclusiveDepthStencil.IsDepthWrite())
	{
		// If depth write is not enabled, we can bound the depth texture as read only
		ForwardBasePassTextures.SceneDepthIfResolved = SceneTextures.Depth.Resolve;
	}
	ForwardBasePassTextures.bIs24BitUnormDepthStencil = ForwardBasePassTextures.SceneDepthIfResolved ? GPixelFormats[ForwardBasePassTextures.SceneDepthIfResolved->Desc.Format].bIs24BitUnormDepthStencil : 1;

	GraphBuilder.SetCommandListStat(GET_STATID(STAT_CLM_BasePass));
	RenderBasePassInternal(GraphBuilder, InViews, SceneTextures, BasePassRenderTargets, BasePassDepthStencilAccess, ForwardBasePassTextures, DBufferTextures, bDoParallelBasePass, bRenderLightmapDensity, InstanceCullingManager, bNaniteEnabled, NaniteBasePassShadingCommands, NaniteRasterResults);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/BasePassRendering.h:66

Scope: file

Source code excerpt:

	FVector4f RectDataAndVirtualShadowMapIdOrPrevLocalLightIndex;
};

struct FForwardBasePassTextures
{
	FRDGTextureRef ScreenSpaceAO = nullptr;
	FRDGTextureRef ScreenSpaceShadowMask = nullptr;
	FRDGTextureRef SceneDepthIfResolved = nullptr;
	bool bIs24BitUnormDepthStencil = false;
};

BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FSharedBasePassUniformParameters,)
	SHADER_PARAMETER_STRUCT(FForwardLightData, Forward)
	SHADER_PARAMETER_STRUCT(FForwardLightData, ForwardISR)
	SHADER_PARAMETER_STRUCT(FReflectionUniformParameters, Reflection)
	SHADER_PARAMETER_STRUCT(FPlanarReflectionUniformParameters, PlanarReflection) // Single global planar reflection for the forward pass.
	SHADER_PARAMETER_STRUCT(FFogUniformParameters, Fog)

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CapsuleShadowRendering.cpp:992

Scope (from outer to inner):

file
function     void FDeferredShadingSceneRenderer::RenderIndirectCapsuleShadows

Source code excerpt:

	if (SceneTextures.Color.IsValid())
	{
		RenderTargets.Emplace(SceneTextures.Color.Target, ERenderTargetLoadAction::ELoad);
	}

	check(SceneTextures.ScreenSpaceAO);
	RenderTargets.Emplace(SceneTextures.ScreenSpaceAO, SceneTextures.ScreenSpaceAO->HasBeenProduced() ? ERenderTargetLoadAction::ELoad : ERenderTargetLoadAction::EClear);

	for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
	{
		const FViewInfo& View = Views[ViewIndex];

		if (View.IndirectShadowPrimitives.Num() > 0 && View.ViewState)
		{
			RDG_GPU_MASK_SCOPE(GraphBuilder, View.GPUMask);
			RDG_GPU_STAT_SCOPE(GraphBuilder, CapsuleShadows);

			int32 NumCapsuleShapes = 0;

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CompositionLighting/CompositionLighting.cpp:598

Scope (from outer to inner):

file
function     void FCompositionLighting::ProcessBeforeBasePass

Source code excerpt:

		}

		if (bEnableSSAO)
		{
			FSSAOCommonParameters Parameters = GetSSAOCommonParameters(GraphBuilder, View, SceneTextures.UniformBuffer, ViewConfig.Levels, false);
			FScreenPassRenderTarget FinalTarget = FScreenPassRenderTarget(SceneTextures.ScreenSpaceAO, View.ViewRect, ERenderTargetLoadAction::ENoAction);

			AddPostProcessingAmbientOcclusion(
				GraphBuilder,
				View,
				Parameters,
				FinalTarget);
		}
	}
}

void FCompositionLighting::ProcessAfterBasePass(FRDGBuilder& GraphBuilder, FInstanceCullingManager& InstanceCullingManager, EProcessAfterBasePassMode Mode)

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CompositionLighting/CompositionLighting.cpp:651

Scope (from outer to inner):

file
function     void FCompositionLighting::ProcessAfterBasePass

Source code excerpt:

		// Forward shading SSAO is applied before the base pass using only the depth buffer.
		if (!IsForwardShadingEnabled(View.GetShaderPlatform()) && Mode != EProcessAfterBasePassMode::OnlyBeforeLightingDecals)
		{
			if (ViewConfig.Levels > 0)
			{
				const bool bScreenSpaceAOIsProduced = SceneTextures.ScreenSpaceAO->HasBeenProduced();
				FScreenPassRenderTarget FinalTarget = FScreenPassRenderTarget(SceneTextures.ScreenSpaceAO, View.ViewRect, bScreenSpaceAOIsProduced ? ERenderTargetLoadAction::ELoad : ERenderTargetLoadAction::ENoAction);

				FScreenPassTexture AmbientOcclusion = bScreenSpaceAOIsProduced ? FinalTarget : FScreenPassTexture();

				// If doing the Split GTAO method then we need to do the second part here.
				if (ViewConfig.GTAOType == EGTAOType::EAsyncHorizonSearch || ViewConfig.GTAOType == EGTAOType::EAsyncCombinedSpatial)
				{
					check(HorizonsTexture);

					FGTAOCommonParameters Parameters = GetGTAOCommonParameters(GraphBuilder, View, SceneTextures.UniformBuffer, ViewConfig.GTAOType);

					FScreenPassTexture GTAOHorizons(HorizonsTexture, Parameters.DownsampledViewRect);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CompositionLighting/CompositionLighting.cpp:685

Scope (from outer to inner):

file
function     void FCompositionLighting::ProcessAfterBasePass

Source code excerpt:

						AmbientOcclusion = AddPostProcessingAmbientOcclusion(GraphBuilder, View, Parameters, FinalTarget);
					}

					if (bEnableDecals)
					{
						DecalPassTextures.ScreenSpaceAO = AmbientOcclusion.Texture;
						AddDeferredDecalPass(GraphBuilder, View, VisibleDecals[ViewIndex], DecalPassTextures, InstanceCullingManager, EDecalRenderStage::AmbientOcclusion);
					}
				}
			}
		}
	}
}

void FCompositionLighting::ProcessAfterOcclusion(FRDGBuilder& GraphBuilder)
{
	if (HasRayTracedOverlay(ViewFamily))

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CompositionLighting/PostProcessAmbientOcclusion.cpp:307

Scope (from outer to inner):

file
function     FRDGTextureDesc GetScreenSpaceAOTextureDesc

Source code excerpt:

	return EGTAOType::EOff;
}

FRDGTextureDesc GetScreenSpaceAOTextureDesc(FIntPoint Extent)
{
	return FRDGTextureDesc(FRDGTextureDesc::Create2D(Extent, PF_G8, FClearValueBinding::White, TexCreate_UAV | TexCreate_RenderTargetable | TexCreate_ShaderResource | GFastVRamConfig.ScreenSpaceAO));
}

FRDGTextureRef CreateScreenSpaceAOTexture(FRDGBuilder& GraphBuilder, FIntPoint Extent)
{	
	return GraphBuilder.CreateTexture(GetScreenSpaceAOTextureDesc(Extent), TEXT("ScreenSpaceAO"));
}

FRDGTextureRef GetScreenSpaceAOFallback(const FRDGSystemTextures& SystemTextures)
{
	return SystemTextures.White;
}

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CompositionLighting/PostProcessDeferredDecals.cpp:229

Scope (from outer to inner):

file
function     void GetDeferredDecalPassParameters

Source code excerpt:

		DepthTexture = Textures.Depth.Resolve;
		break;
	}
	case EDecalRenderTargetMode::AmbientOcclusion:
	{
		AddColorTarget(Textures.ScreenSpaceAO);
		break;
	}

	default:
		checkNoEntry();
	}

	RenderTargets.DepthStencil = FDepthStencilBinding(
		DepthTexture,
		ERenderTargetLoadAction::ELoad,
		ERenderTargetLoadAction::ELoad,

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CompositionLighting/PostProcessDeferredDecals.cpp:586

Scope (from outer to inner):

file
function     void AddDeferredDecalPass

Source code excerpt:

	const uint32 MeshDecalCount = View.MeshDecalBatches.Num();
	const uint32 DecalCount = Scene.Decals.Num();
	uint32 SortedDecalCount = 0;
	FTransientDecalRenderDataList* SortedDecals = nullptr;

	checkf(DecalRenderStage != EDecalRenderStage::AmbientOcclusion || PassTextures.ScreenSpaceAO, TEXT("Attepting to render AO decals without SSAO having emitted a valid render target."));
	checkf(DecalRenderStage != EDecalRenderStage::BeforeBasePass || IsUsingDBuffers(ShaderPlatform), TEXT("Only DBuffer decals are supported before the base pass."));

	if (!VisibleDecals.IsEmpty())
	{
		SortedDecals = GraphBuilder.AllocObject<FTransientDecalRenderDataList>();
		DecalRendering::BuildRelevantDecalList(VisibleDecals, DecalRenderStage, SortedDecals);
		SortedDecalCount = SortedDecals->Num();

		INC_DWORD_STAT_BY(STAT_Decals, SortedDecalCount);
	}

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CompositionLighting/PostProcessDeferredDecals.h:29

Scope: file

Source code excerpt:

	TRDGUniformBufferRef<FDecalPassUniformParameters> DecalPassUniformBuffer = nullptr;

	// Potential render targets for the decal pass.
	FRDGTextureMSAA Depth;
	FRDGTextureRef Color = nullptr;
	FRDGTextureRef ScreenSpaceAO = nullptr;
	FRDGTextureRef GBufferA = nullptr;
	FRDGTextureRef GBufferB = nullptr;
	FRDGTextureRef GBufferC = nullptr;
	FRDGTextureRef GBufferE = nullptr;
	FDBufferTextures* DBufferTextures = nullptr;
};

FDeferredDecalPassTextures GetDeferredDecalPassTextures(
	FRDGBuilder& GraphBuilder, 
	const FSceneView& ViewInfo,
	const FSceneTextures& SceneTextures, 

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/IndirectLightRendering.cpp:1190

Scope (from outer to inner):

file
function     void FDeferredShadingSceneRenderer::RenderDiffuseIndirectAndAmbientOcclusion

Source code excerpt:

			check(AmbientOcclusionMask);
		}
		else if (ViewPipelineState.AmbientOcclusionMethod == EAmbientOcclusionMethod::SSAO)
		{
			// Fetch result of SSAO that was done earlier.
			if (HasBeenProduced(SceneTextures.ScreenSpaceAO))
			{
				AmbientOcclusionMask = SceneTextures.ScreenSpaceAO;
			}
			else
			{
				AmbientOcclusionMask = GetScreenSpaceAOFallback(SystemTextures);
				bWritableAmbientOcclusionMask = false;
			}
		}
		else
		{
			unimplemented();
			bWritableAmbientOcclusionMask = false;

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/IndirectLightRendering.cpp:1211

Scope (from outer to inner):

file
function     void FDeferredShadingSceneRenderer::RenderDiffuseIndirectAndAmbientOcclusion

Source code excerpt:

		// Extract the dynamic AO for application of AO beyond RenderDiffuseIndirectAndAmbientOcclusion()
		if (AmbientOcclusionMask && ViewPipelineState.AmbientOcclusionMethod != EAmbientOcclusionMethod::SSAO)
		{
			//ensureMsgf(!bApplySSAO, TEXT("Looks like SSAO has been computed for this view but is being overridden."));
			ensureMsgf(Views.Num() == 1, TEXT("Need to add support for one AO texture per view in FSceneTextures")); // TODO.
			SceneTextures.ScreenSpaceAO = AmbientOcclusionMask;
		}

		if (HairStrands::HasViewHairStrandsData(View) && (ViewPipelineState.AmbientOcclusionMethod == EAmbientOcclusionMethod::SSGI || ViewPipelineState.AmbientOcclusionMethod == EAmbientOcclusionMethod::SSAO) && bWritableAmbientOcclusionMask)
		{
			RenderHairStrandsAmbientOcclusion(
				GraphBuilder,
				View,
				AmbientOcclusionMask);
		}

		// Applies diffuse indirect and ambient occlusion to the scene color.

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/IndirectLightRendering.cpp:1707

Scope (from outer to inner):

file
function     static void AddSkyReflectionPass

Source code excerpt:

	bool bHasSphereCaptures = (View.NumSphereReflectionCaptures > 0);
	bool bIsTiledSSR = ScreenSpaceReflectionTileClassification.TileMaskBuffer != nullptr;

	float DynamicBentNormalAO = DynamicBentNormalAOTexture ? 1.0f : 0.0f;
	const FRDGSystemTextures& SystemTextures = FRDGSystemTextures::Get(GraphBuilder);
	FRDGTextureRef AmbientOcclusionTexture = HasBeenProduced(SceneTextures.ScreenSpaceAO) ? SceneTextures.ScreenSpaceAO : GetScreenSpaceAOFallback(SystemTextures);

	const auto& SceneColorTexture = SceneTextures.Color;

	FReflectionEnvironmentSkyLightingParameters* PassParameters = GraphBuilder.AllocParameters<FReflectionEnvironmentSkyLightingParameters>();

	// Setup the parameters of the shader.
	{
		// Setups all shader parameters related to skylight.
		PassParameters->PS.SkyDiffuseLighting = GetSkyDiffuseLightingParameters(Scene->SkyLight, DynamicBentNormalAO);

		// Setups all shader parameters related to distance field AO

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/MobileBasePassRendering.cpp:296

Scope (from outer to inner):

file
function     void SetupMobileBasePassUniformParameters

Source code excerpt:

	BasePassParameters.PreIntegratedGFTexture = GSystemTextures.PreintegratedGF->GetRHI();
	BasePassParameters.PreIntegratedGFSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
	BasePassParameters.EyeAdaptationBuffer = GraphBuilder.CreateSRV(GetEyeAdaptationBuffer(GraphBuilder, View));

	FRDGTextureRef AmbientOcclusionTexture = SystemTextures.White;
	if (BasePass == EMobileBasePass::Opaque && MobileBasePassTextures.ScreenSpaceAO != nullptr)
	{
		AmbientOcclusionTexture = MobileBasePassTextures.ScreenSpaceAO;
	}
	
	BasePassParameters.DBuffer = GetDBufferParameters(GraphBuilder, MobileBasePassTextures.DBufferTextures, View.GetShaderPlatform());

	BasePassParameters.AmbientOcclusionTexture = AmbientOcclusionTexture;
	BasePassParameters.AmbientOcclusionSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
	BasePassParameters.AmbientOcclusionStaticFraction = FMath::Clamp(View.FinalPostProcessSettings.AmbientOcclusionStaticFraction, 0.0f, 1.0f);

	const bool bMobileUsesShadowMaskTexture = MobileUsesShadowMaskTexture(View.GetShaderPlatform());
	
	if (bMobileUsesShadowMaskTexture && GScreenSpaceShadowMaskTextureMobileOutputs.ScreenSpaceShadowMaskTextureMobile.IsValid())

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/MobileBasePassRendering.h:32

Scope: file

Source code excerpt:

bool MobileMergeLocalLightsInPrepassEnabled(const FStaticShaderPlatform Platform);
bool MobileMergeLocalLightsInBasepassEnabled(const FStaticShaderPlatform Platform);

struct FMobileBasePassTextures
{
	FRDGTextureRef ScreenSpaceAO = nullptr;
	FDBufferTextures DBufferTextures = {};
};

BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FMobileBasePassUniformParameters, )
	SHADER_PARAMETER(float, AmbientOcclusionStaticFraction)
	SHADER_PARAMETER_STRUCT(FFogUniformParameters, Fog)
	SHADER_PARAMETER_STRUCT(FLocalFogVolumeUniformParameters, LFV)
	SHADER_PARAMETER_STRUCT(FForwardLightData, Forward)
	SHADER_PARAMETER_STRUCT(FForwardLightData, ForwardMMV)
	SHADER_PARAMETER_STRUCT(FPlanarReflectionUniformParameters, PlanarReflection) // Single global planar reflection for the forward pass.
	SHADER_PARAMETER_STRUCT(FMobileSceneTextureUniformParameters, SceneTextures)

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/MobileShadingRenderer.cpp:1269

Scope (from outer to inner):

file
function     void FMobileSceneRenderer::Render

Source code excerpt:

		}

		// When renderer is in ERendererOutput::DepthPrepassOnly mode, bRequiresAmbientOcclusionPass is set to false in InitViews()
		if (bRequiresAmbientOcclusionPass)
		{
			RenderAmbientOcclusion(GraphBuilder, SceneTextures.Depth.Resolve, SceneTextures.ScreenSpaceAO);
		}

		// Local Light prepass

		if (bRendererOutputFinalSceneColor)
		{
			RenderMobileLocalLightsBuffer(GraphBuilder, SceneTextures, SortedLightSet);
		}

		if (bRendererOutputFinalSceneColor)
		{

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/MobileShadingRenderer.cpp:1542

Scope (from outer to inner):

file
function     void FMobileSceneRenderer::RenderForward

Source code excerpt:

		View.BeginRenderView();

		UpdateDirectionalLightUniformBuffers(GraphBuilder, View);

		FMobileBasePassTextures MobileBasePassTextures{};
		MobileBasePassTextures.ScreenSpaceAO = bRequiresAmbientOcclusionPass ? SceneTextures.ScreenSpaceAO : SystemTextures.White;
		MobileBasePassTextures.DBufferTextures = DBufferTextures;

		EMobileSceneTextureSetupMode SetupMode = (bIsFullDepthPrepassEnabled ? EMobileSceneTextureSetupMode::SceneDepth : EMobileSceneTextureSetupMode::None) | EMobileSceneTextureSetupMode::CustomDepth;
		FMobileRenderPassParameters* PassParameters = GraphBuilder.AllocParameters<FMobileRenderPassParameters>();
		PassParameters->View = View.GetShaderParameters();
		PassParameters->MobileBasePass = CreateMobileBasePassUniformBuffer(GraphBuilder, View, EMobileBasePass::Opaque, SetupMode, MobileBasePassTextures);
		PassParameters->ReflectionCapture = View.MobileReflectionCaptureUniformBuffer;
		PassParameters->RenderTargets = BasePassRenderTargets;
		PassParameters->LocalFogVolumeInstances = View.LocalFogVolumeViewData.GPUInstanceDataBufferSRV;
		PassParameters->LocalFogVolumeTileDrawIndirectBuffer = View.LocalFogVolumeViewData.GPUTileDrawIndirectBuffer;
		PassParameters->LocalFogVolumeTileDataTexture = View.LocalFogVolumeViewData.TileDataTextureArraySRV;

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/MobileShadingRenderer.cpp:1913

Scope (from outer to inner):

file
function     void FMobileSceneRenderer::RenderDeferred

Source code excerpt:

		View.BeginRenderView();

		UpdateDirectionalLightUniformBuffers(GraphBuilder, View);

		FMobileBasePassTextures MobileBasePassTextures{};
		MobileBasePassTextures.ScreenSpaceAO = bRequiresAmbientOcclusionPass ? SceneTextures.ScreenSpaceAO : SystemTextures.White;

		EMobileSceneTextureSetupMode SetupMode = (bIsFullDepthPrepassEnabled ? EMobileSceneTextureSetupMode::SceneDepth : EMobileSceneTextureSetupMode::None) | EMobileSceneTextureSetupMode::CustomDepth;
		auto* PassParameters = GraphBuilder.AllocParameters<FMobileRenderPassParameters>();
		PassParameters->View = View.GetShaderParameters();
		PassParameters->MobileBasePass = CreateMobileBasePassUniformBuffer(GraphBuilder, View, EMobileBasePass::Opaque, SetupMode, MobileBasePassTextures);
		PassParameters->ReflectionCapture = View.MobileReflectionCaptureUniformBuffer;
		PassParameters->RenderTargets = BasePassRenderTargets;
		PassParameters->LocalFogVolumeInstances = View.LocalFogVolumeViewData.GPUInstanceDataBufferSRV;
		PassParameters->LocalFogVolumeTileDrawIndirectBuffer = View.LocalFogVolumeViewData.GPUTileDrawIndirectBuffer;
		PassParameters->LocalFogVolumeTileDataTexture = View.LocalFogVolumeViewData.TileDataTextureArraySRV;
		PassParameters->LocalFogVolumeTileDataBuffer = View.LocalFogVolumeViewData.GPUTileDataBufferSRV;

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneRendering.cpp:490

Scope: file

Source code excerpt:

FASTVRAM_CVAR(Distortion, 1);
FASTVRAM_CVAR(ScreenSpaceShadowMask, 1);
FASTVRAM_CVAR(VolumetricFog, 1);
FASTVRAM_CVAR(SeparateTranslucency, 0); 
FASTVRAM_CVAR(SeparateTranslucencyModulate, 0);
FASTVRAM_CVAR(ScreenSpaceAO,0);
FASTVRAM_CVAR(SSR, 0);
FASTVRAM_CVAR(DBufferA, 0);
FASTVRAM_CVAR(DBufferB, 0);
FASTVRAM_CVAR(DBufferC, 0); 
FASTVRAM_CVAR(DBufferMask, 0);
FASTVRAM_CVAR(DOFSetup, 1);
FASTVRAM_CVAR(DOFReduce, 1);
FASTVRAM_CVAR(DOFPostfilter, 1);
FASTVRAM_CVAR(PostProcessMaterial, 1);

FASTVRAM_CVAR(CustomDepth, 0);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneRendering.cpp:690

Scope (from outer to inner):

file
function     void FFastVramConfig::Update

Source code excerpt:

	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_Distortion, Distortion);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_ScreenSpaceShadowMask, ScreenSpaceShadowMask);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_VolumetricFog, VolumetricFog);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_SeparateTranslucency, SeparateTranslucency);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_SeparateTranslucencyModulate, SeparateTranslucencyModulate);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_ScreenSpaceAO, ScreenSpaceAO);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_SSR, SSR);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_DBufferA, DBufferA);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_DBufferB, DBufferB);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_DBufferC, DBufferC);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_DBufferMask, DBufferMask);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_DOFSetup, DOFSetup);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_DOFReduce, DOFReduce);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_DOFPostfilter, DOFPostfilter);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_CustomDepth, CustomDepth);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_ShadowPointLight, ShadowPointLight);
	bDirty |= UpdateTextureFlagFromCVar(CVarFastVRam_ShadowPerObject, ShadowPerObject);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneRendering.h:2840

Scope: file

Source code excerpt:

	ETextureCreateFlags Distortion;
	ETextureCreateFlags ScreenSpaceShadowMask;
	ETextureCreateFlags VolumetricFog;
	ETextureCreateFlags SeparateTranslucency;
	ETextureCreateFlags SeparateTranslucencyModulate;
	ETextureCreateFlags ScreenSpaceAO;
	ETextureCreateFlags SSR;
	ETextureCreateFlags DBufferA;
	ETextureCreateFlags DBufferB;
	ETextureCreateFlags DBufferC;
	ETextureCreateFlags DBufferMask;
	ETextureCreateFlags DOFSetup;
	ETextureCreateFlags DOFReduce;
	ETextureCreateFlags DOFPostfilter;
	ETextureCreateFlags PostProcessMaterial;

	ETextureCreateFlags CustomDepth;

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneTextures.cpp:518

Scope (from outer to inner):

file
function     void FSceneTextures::InitializeViewFamily

Source code excerpt:

	FMinimalSceneTextures::InitializeViewFamily(GraphBuilder, ViewFamily);

	if (Config.ShadingPath == EShadingPath::Deferred)
	{
		// Screen Space Ambient Occlusion
		SceneTextures.ScreenSpaceAO = CreateScreenSpaceAOTexture(GraphBuilder, Config.Extent);

		// Small Depth
		const FIntPoint SmallDepthExtent = GetDownscaledExtent(Config.Extent, Config.SmallDepthDownsampleFactor);
		const FRDGTextureDesc SmallDepthDesc(FRDGTextureDesc::Create2D(SmallDepthExtent, PF_DepthStencil, FClearValueBinding::None, TexCreate_DepthStencilTargetable | TexCreate_ShaderResource));
		SceneTextures.SmallDepth = GraphBuilder.CreateTexture(SmallDepthDesc, TEXT("SmallDepthZ"));
	}
	else
	{
		// Mobile Screen Space Ambient Occlusion
		SceneTextures.ScreenSpaceAO = CreateMobileScreenSpaceAOTexture(GraphBuilder, Config);

		if (Config.MobilePixelProjectedReflectionExtent != FIntPoint::ZeroValue)
		{
			SceneTextures.PixelProjectedReflection = CreateMobilePixelProjectedReflectionTexture(GraphBuilder, Config.MobilePixelProjectedReflectionExtent);
		}
	}

	// Velocity
	SceneTextures.Velocity = GraphBuilder.CreateTexture(FVelocityRendering::GetRenderTargetDesc(Config.ShaderPlatform, Config.Extent), TEXT("SceneVelocity"));

	if (Config.bIsUsingGBuffers)

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneTextures.cpp:790

Scope (from outer to inner):

file
function     FRDGTextureRef GetSceneTexture

Source code excerpt:

	case ESceneTexture::GBufferB:       return SceneTextures.GBufferB;
	case ESceneTexture::GBufferC:       return SceneTextures.GBufferC;
	case ESceneTexture::GBufferD:       return SceneTextures.GBufferD;
	case ESceneTexture::GBufferE:       return SceneTextures.GBufferE;
	case ESceneTexture::GBufferF:       return SceneTextures.GBufferF;
	case ESceneTexture::SSAO:           return SceneTextures.ScreenSpaceAO;
	case ESceneTexture::CustomDepth:	return SceneTextures.CustomDepth.Depth;
	default:
		checkNoEntry();
		return nullptr;
	}
}

void SetupSceneTextureUniformParameters(
	FRDGBuilder& GraphBuilder,
	const FSceneTextures* SceneTextures,
	ERHIFeatureLevel::Type FeatureLevel,

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneTextures.cpp:875

Scope (from outer to inner):

file
function     void SetupSceneTextureUniformParameters

Source code excerpt:

		if (EnumHasAnyFlags(SetupMode, ESceneTextureSetupMode::SceneVelocity) && HasBeenProduced(SceneTextures->Velocity))
		{
			SceneTextureParameters.GBufferVelocityTexture = SceneTextures->Velocity;
		}

		if (EnumHasAnyFlags(SetupMode, ESceneTextureSetupMode::SSAO) && HasBeenProduced(SceneTextures->ScreenSpaceAO))
		{
			SceneTextureParameters.ScreenSpaceAOTexture = SceneTextures->ScreenSpaceAO;
		}

		if (EnumHasAnyFlags(SetupMode, ESceneTextureSetupMode::CustomDepth))
		{
			const FCustomDepthTextures& CustomDepthTextures = SceneTextures->CustomDepth;

			if (HasBeenProduced(CustomDepthTextures.Depth))
			{
				SceneTextureParameters.CustomDepthTexture = CustomDepthTextures.Depth;
				SceneTextureParameters.CustomStencilTexture = CustomDepthTextures.Stencil;
			}