Files
UnrealEngine/Engine/Shaders/Private/RayTracing/RayTracingSkyLightRGS.usf
2025-05-18 13:04:45 +08:00

102 lines
3.4 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#include "../Common.ush"
#include "../SceneTextureParameters.ush"
#include "../PathTracing/Utilities/PathTracingRandomSequence.ush"
#if USE_HAIR_LIGHTING
#include "../HairStrands/HairStrandsRaytracing.ush"
#endif
#include "RayTracingSkyLightEvaluation.ush"
#include "RayTracingDeferredShadingCommon.ush"
uint UpscaleFactor;
RaytracingAccelerationStructure TLAS;
RWTexture2D<float4> RWSkyOcclusionMaskUAV;
RWTexture2D<float2> RWSkyOcclusionRayDistanceUAV;
RAY_TRACING_ENTRY_RAYGEN(SkyLightRGS)
{
uint2 DispatchThreadId = DispatchRaysIndex().xy + View.ViewRectMin.xy;
uint2 PixelCoord = GetPixelCoord(DispatchThreadId, UpscaleFactor);
#if SUBSTRATE_ENABLED
RWSkyOcclusionMaskUAV[DispatchThreadId] = float4(0,0,0,1);
RWSkyOcclusionRayDistanceUAV[DispatchThreadId] = float2(200000, 0);
#else // SUBSTRATE_ENABLED
// Get G-Buffer surface data
float2 InvBufferSize = View.BufferSizeAndInvSize.zw;
float2 UV = (float2(PixelCoord) + 0.5) * InvBufferSize;
FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(UV);
#if 0
FGBufferData GBufferData = GetGBufferDataFromSceneTextures(UV);
#else
//#dxr-todo: workaround for flickering. UE-87281
FGBufferData GBufferData = GetGBufferDataFromSceneTexturesLoad(PixelCoord);
#endif
float DeviceZ = SceneDepthTexture.Load(int3(PixelCoord, 0)).r;
float3 TranslatedWorldPosition;
float3 CameraDirection;
ReconstructTranslatedWorldPositionAndCameraDirectionFromDeviceZ(PixelCoord, DeviceZ, TranslatedWorldPosition, CameraDirection);
float3 WorldNormal = GBufferData.WorldNormal;
float3 Albedo = GBufferData.DiffuseColor;
// Recalculate DiffuseColor if subsurface reverted the contribution within the G-Buffer
if (UseSubsurfaceProfile(GBufferData.ShadingModelID))
{
Albedo = GBufferData.StoredBaseColor - GBufferData.StoredBaseColor * GBufferData.Metallic;
GBufferData.DiffuseColor = Albedo;
}
// Mask out depth values that are infinitely far away
bool IsFiniteDepth = DeviceZ > 0.0;
bool bTraceRay = (
IsFiniteDepth &&
GBufferData.ShadingModelID != SHADINGMODELID_UNLIT);
uint SamplesPerPixel = SkyLight.SamplesPerPixel;
if (!bTraceRay)
{
SamplesPerPixel = 0;
}
// Evaluate the Sky Light at the surface point
const bool bGBufferSampleOrigin = true;
const bool bDecoupleSampleGeneration = DECOUPLE_SAMPLE_GENERATION != 0;
float3 ExitantRadiance;
float3 DiffuseExitantRadiance;
float AmbientOcclusion;
float HitDistance;
SkyLightEvaluate(
DispatchThreadId,
PixelCoord,
SamplesPerPixel,
TranslatedWorldPosition,
WorldNormal,
CameraDirection,
GBufferData,
TLAS,
bGBufferSampleOrigin,
DeviceZ,
bDecoupleSampleGeneration,
ExitantRadiance,
DiffuseExitantRadiance,
AmbientOcclusion,
HitDistance);
// Pre-divide by albedo, to be recovered in compositing
DiffuseExitantRadiance.r = Albedo.r > 0.0 ? DiffuseExitantRadiance.r / Albedo.r : DiffuseExitantRadiance.r;
DiffuseExitantRadiance.g = Albedo.g > 0.0 ? DiffuseExitantRadiance.g / Albedo.g : DiffuseExitantRadiance.g;
DiffuseExitantRadiance.b = Albedo.b > 0.0 ? DiffuseExitantRadiance.b / Albedo.b : DiffuseExitantRadiance.b;
DiffuseExitantRadiance.rgb *= View.PreExposure;
RWSkyOcclusionMaskUAV[DispatchThreadId] = float4(ClampToHalfFloatRange(DiffuseExitantRadiance.rgb), AmbientOcclusion);
RWSkyOcclusionRayDistanceUAV[DispatchThreadId] = float2(HitDistance, SamplesPerPixel);
#endif // SUBSTRATE_ENABLED
}