Files
UnrealEngine/Engine/Source/Runtime/Renderer/Private/SkyAtmosphereRendering.h
2025-05-18 13:04:45 +08:00

256 lines
10 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
SkyAtmosphereRendering.h
=============================================================================*/
#pragma once
#include "EngineDefines.h"
#include "RenderGraph.h"
#include "RenderResource.h"
#include "Rendering/SkyAtmosphereCommonData.h"
#include "RenderGraphResources.h"
#include "SceneView.h"
#include "VirtualShadowMaps/VirtualShadowMapArray.h"
class FScene;
class FViewInfo;
class FLightSceneInfo;
class FVisibleLightInfo;
class USkyAtmosphereComponent;
class FSkyAtmosphereSceneProxy;
class FProjectedShadowInfo;
class FSkyAtmosphereInternalCommonParameters;
class FVolumeShadowingShaderParametersGlobal0;
class FVolumeShadowingShaderParametersGlobal1;
struct FScreenPassTexture;
struct FEngineShowFlags;
DECLARE_UNIFORM_BUFFER_STRUCT(FSceneUniformParameters, RENDERER_API)
// Use as a global shader parameter struct and also the CPU structure representing the atmosphere it self.
// This is static for a version of a component. When a component is changed/tweaked, it is recreated.
BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FAtmosphereUniformShaderParameters, )
SHADER_PARAMETER(float, MultiScatteringFactor)
SHADER_PARAMETER(float, BottomRadiusKm)
SHADER_PARAMETER(float, TopRadiusKm)
SHADER_PARAMETER(float, RayleighDensityExpScale)
SHADER_PARAMETER(FLinearColor, RayleighScattering)
SHADER_PARAMETER(FLinearColor, MieScattering)
SHADER_PARAMETER(float, MieDensityExpScale)
SHADER_PARAMETER(FLinearColor, MieExtinction)
SHADER_PARAMETER(float, MiePhaseG)
SHADER_PARAMETER(FLinearColor, MieAbsorption)
SHADER_PARAMETER(float, AbsorptionDensity0LayerWidth)
SHADER_PARAMETER(float, AbsorptionDensity0ConstantTerm)
SHADER_PARAMETER(float, AbsorptionDensity0LinearTerm)
SHADER_PARAMETER(float, AbsorptionDensity1ConstantTerm)
SHADER_PARAMETER(float, AbsorptionDensity1LinearTerm)
SHADER_PARAMETER(FLinearColor, AbsorptionExtinction)
SHADER_PARAMETER(FLinearColor, GroundAlbedo)
END_GLOBAL_SHADER_PARAMETER_STRUCT()
// These parameters are shared on the view global uniform buffer and are dynamically changed with cvars.
struct FSkyAtmosphereViewSharedUniformShaderParameters
{
FVector4f CameraAerialPerspectiveVolumeSizeAndInvSize;
float AerialPerspectiveStartDepthKm;
float CameraAerialPerspectiveVolumeDepthResolution;
float CameraAerialPerspectiveVolumeDepthResolutionInv;
float CameraAerialPerspectiveVolumeDepthSliceLengthKm;
float CameraAerialPerspectiveVolumeDepthSliceLengthKmInv;
float ApplyCameraAerialPerspectiveVolume;
};
// Structure with data necessary to specify a sky render.
struct FSkyAtmosphereRenderContext
{
///////////////////////////////////
// Per scene parameters
bool bUseDepthBoundTestIfPossible;
bool bForceRayMarching;
bool bDepthReadDisabled;// Do not apply scene depth texture. As such, only far Z will be considered
bool bDisableBlending; // Do not do any blending. The sky will clear the target when rendering a sky reflection capture for instance.
bool bFastSky;
bool bFastAerialPerspective;
bool bFastAerialPerspectiveDepthTest;
bool bSecondAtmosphereLightEnabled;
bool bShouldSampleOpaqueShadow;
FRDGTextureRef TransmittanceLut;
FRDGTextureRef MultiScatteredLuminanceLut;
FRDGTextureRef SkyAtmosphereViewLutTexture;
FRDGTextureRef SkyAtmosphereCameraAerialPerspectiveVolume;
FRDGTextureRef SkyAtmosphereCameraAerialPerspectiveVolumeMieOnly;
FRDGTextureRef SkyAtmosphereCameraAerialPerspectiveVolumeRayOnly;
///////////////////////////////////
// Per view parameters
FViewMatrices* ViewMatrices; // The actual view matrices we use to render the sky
TUniformBufferRef<FViewUniformShaderParameters> ViewUniformBuffer;
TRDGUniformBufferRef<FSceneUniformParameters> SceneUniformBuffer;
bool bSceneHasSkyMaterial;
FRenderTargetBindingSlots RenderTargets;
FIntRect Viewport;
bool bIsReflectionCapture;
bool bRenderSkyPixel;
float AerialPerspectiveStartDepthInCm;
float NearClippingDistance;
ERHIFeatureLevel::Type FeatureLevel;
TRDGUniformBufferRef<FVolumeShadowingShaderParametersGlobal0> LightShadowShaderParams0UniformBuffer{};
TRDGUniformBufferRef<FVolumeShadowingShaderParametersGlobal1> LightShadowShaderParams1UniformBuffer{};
int VirtualShadowMapId0 = INDEX_NONE;
int VirtualShadowMapId1 = INDEX_NONE;
bool bShouldSampleCloudShadow;
FRDGTextureRef VolumetricCloudShadowMap[2];
bool bShouldSampleCloudSkyAO;
FRDGTextureRef VolumetricCloudSkyAO;
bool bAPOnCloudMode;
FRDGTextureRef VolumetricCloudDepthTexture;
FRDGTextureRef InputCloudLuminanceTransmittanceTexture;
uint8 MSAASampleCount;
FRDGTextureRef MSAADepthTexture;
FSkyAtmosphereRenderContext();
private:
};
class FSkyAtmosphereRenderSceneInfo
{
public:
/** Initialization constructor. */
explicit FSkyAtmosphereRenderSceneInfo(FSkyAtmosphereSceneProxy& SkyAtmosphereSceneProxy);
~FSkyAtmosphereRenderSceneInfo();
const TUniformBufferRef<FAtmosphereUniformShaderParameters>& GetAtmosphereUniformBuffer() { return AtmosphereUniformBuffer; }
TRefCountPtr<IPooledRenderTarget>& GetTransmittanceLutTexture() { return TransmittanceLutTexture; }
TRefCountPtr<IPooledRenderTarget>& GetMultiScatteredLuminanceLutTexture() { return MultiScatteredLuminanceLutTexture; }
void CreateDistantSkyLightLutBufferAndSRV(FRDGBuilder& GraphBuilder);
TRefCountPtr<FRDGPooledBuffer>& GetDistantSkyLightLutBuffer();
TRefCountPtr<FRDGPooledBuffer>& GetMobileDistantSkyLightLutBuffer();
FRHIShaderResourceView* GetDistantSkyLightLutBufferSRV();
FRHIShaderResourceView* GetMobileDistantSkyLightLutBufferSRV();
FRDGTextureRef GetTransmittanceLutTexture(FRDGBuilder& GraphBuilder) const { return GraphBuilder.RegisterExternalTexture(TransmittanceLutTexture); }
const FAtmosphereUniformShaderParameters* GetAtmosphereShaderParameters() const { return &AtmosphereUniformShaderParameters; }
const FSkyAtmosphereSceneProxy& GetSkyAtmosphereSceneProxy() const { return SkyAtmosphereSceneProxy; }
TUniformBufferRef<FSkyAtmosphereInternalCommonParameters>& GetInternalCommonParametersUniformBuffer() { return InternalCommonParametersUniformBuffer; }
private:
FSkyAtmosphereSceneProxy& SkyAtmosphereSceneProxy;
FAtmosphereUniformShaderParameters AtmosphereUniformShaderParameters;
TUniformBufferRef<FAtmosphereUniformShaderParameters> AtmosphereUniformBuffer;
TUniformBufferRef<FSkyAtmosphereInternalCommonParameters> InternalCommonParametersUniformBuffer;
TRefCountPtr<IPooledRenderTarget> TransmittanceLutTexture;
TRefCountPtr<IPooledRenderTarget> MultiScatteredLuminanceLutTexture;
TRefCountPtr<FRDGPooledBuffer> DistantSkyLightLutBuffer;
FRHIShaderResourceView* DistantSkyLightLutBufferSRV = nullptr;
TRefCountPtr<FRDGPooledBuffer> MobileDistantSkyLightLutBuffer;
FRHIShaderResourceView* MobileDistantSkyLightLutBufferSRV = nullptr;
};
/** Pending RDG resource to commit after the pre-pass / nanite rasterization so that RenderSkyAtmosphereLookUpTables() can overlap them on async compute. */
class FSkyAtmospherePendingRDGResources
{
public:
// Sky env map capture uses the view UB, which contains the LUTs computed above. We need to transition them to readable now.
void CommitToSceneAndViewUniformBuffers(FRDGBuilder& GraphBuilder, FRDGExternalAccessQueue& ExternalAccessQueue) const;
private:
struct FViewRDGResources
{
FRDGTextureRef SkyAtmosphereViewLutTexture = nullptr;
FRDGTextureRef SkyAtmosphereCameraAerialPerspectiveVolume = nullptr;
};
FSceneRenderer* SceneRenderer = nullptr;
TArray<FViewRDGResources, TInlineAllocator<4>> ViewResources;
FRDGBufferRef DistantSkyLightLutBuffer = nullptr;
FRDGBufferRef MobileDistantSkyLightLutBuffer = nullptr;
FRDGTextureRef RealTimeReflectionCaptureSkyAtmosphereViewLutTexture = nullptr;
FRDGTextureRef RealTimeReflectionCaptureCamera360APLutTexture = nullptr;
FRDGTextureRef TransmittanceLut = nullptr;
friend class FSceneRenderer;
};
enum class ESkyAtmospherePassLocation : uint32
{
// Renders just before the BasePass.
BeforeBasePass,
// Renders just before the PrePass but can overlap on async compute with it too.
BeforePrePass,
};
// Returns the location in the frame where SkyAtmosphere is rendered.
extern ESkyAtmospherePassLocation GetSkyAtmospherePassLocation();
bool ShouldRenderSkyAtmosphere(const FScene* Scene, const FEngineShowFlags& EngineShowFlags);
void InitSkyAtmosphereForScene(FRHICommandListImmediate& RHICmdList, FRDGBuilder& GraphBuilder, FScene* Scene);
void InitSkyAtmosphereForView(FRHICommandListImmediate& RHICmdList, const FScene* Scene, FViewInfo& View);
extern void SetupSkyAtmosphereViewSharedUniformShaderParameters(const class FViewInfo& View, const FSkyAtmosphereSceneProxy& SkyAtmosphereProxy, FSkyAtmosphereViewSharedUniformShaderParameters& OutParameters);
// Prepare the sun light data as a function of the atmosphere state.
void PrepareSunLightProxy(const FSkyAtmosphereRenderSceneInfo& SkyAtmosphere, uint32 AtmosphereLightIndex, FLightSceneInfo& AtmosphereLight);
bool IsLightAtmospherePerPixelTransmittanceEnabled(const FScene* Scene, const FViewInfo& View, const FLightSceneInfo* const LightSceneInfo);
float GetValidAerialPerspectiveStartDepthInCm(const FViewInfo& View, const FSkyAtmosphereSceneProxy& SkyAtmosphereProxy);
struct SkyAtmosphereLightShadowData
{
const FLightSceneInfo* LightVolumetricShadowSceneinfo0 = nullptr;
const FLightSceneInfo* LightVolumetricShadowSceneinfo1 = nullptr;
const FProjectedShadowInfo* ProjectedShadowInfo0 = nullptr;
const FProjectedShadowInfo* ProjectedShadowInfo1 = nullptr;
int VirtualShadowMapId0 = INDEX_NONE;
int VirtualShadowMapId1 = INDEX_NONE;
};
bool ShouldSkySampleAtmosphereLightsOpaqueShadow(const FScene& Scene, const TArray<FVisibleLightInfo, SceneRenderingAllocator>& VisibleLightInfos, SkyAtmosphereLightShadowData& LightShadowData);
void GetSkyAtmosphereLightsUniformBuffers(
FRDGBuilder& GraphBuilder,
TRDGUniformBufferRef<FVolumeShadowingShaderParametersGlobal0>& OutLightShadowShaderParams0UniformBuffer,
TRDGUniformBufferRef<FVolumeShadowingShaderParametersGlobal1>& OutLightShadowShaderParams1UniformBuffer,
const SkyAtmosphereLightShadowData& LightShadowData,
const FViewInfo& ViewInfo,
const bool bShouldSampleOpaqueShadow,
const EUniformBufferUsage UniformBufferUsage);
bool ShouldRenderSkyAtmosphereDebugPasses(const FScene* Scene, const FEngineShowFlags& EngineShowFlags);
FScreenPassTexture AddSkyAtmosphereDebugPasses(FRDGBuilder& GraphBuilder, FScene* Scene, const FSceneViewFamily& ViewFamily, const FViewInfo& View, FScreenPassTexture& ScreenPassSceneColor);