Files
UnrealEngine/Engine/Shaders/Private/Lumen/LumenTranslucencyVolumeLightingShared.ush
2025-05-18 13:04:45 +08:00

113 lines
4.0 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
LumenTranslucencyLightingShared.ush
=============================================================================*/
#pragma once
#include "../BlueNoise.ush"
#include "../HZB.ush"
#define PROBE_SOURCE_MODE_NONE 0
#define PROBE_SOURCE_MODE_RADIANCE_CACHE 1
#define PROBE_SOURCE_MODE_FROXEL 2
uint TranslucencyVolumeTracingOctahedronResolution;
uint3 TranslucencyGIGridSize;
float3 TranslucencyGIGridZParams;
uint TranslucencyGIGridPixelSizeShift;
int FroxelDirectionJitterFrameIndex;
float3 FrameJitterOffset;
float4x4 UnjitteredClipToTranslatedWorld;
float GridCenterOffsetFromDepthBuffer;
float GridCenterOffsetThresholdToAcceptDepthBufferOffset;
float ComputeDepthFromZSlice(float ZSlice)
{
float SliceDepth = (exp2(ZSlice / TranslucencyGIGridZParams.z) - TranslucencyGIGridZParams.y) / TranslucencyGIGridZParams.x;
return SliceDepth;
}
float ComputeZSliceFromDepth(float SliceDepth)
{
float ZSlice = log2(SliceDepth * TranslucencyGIGridZParams.x + TranslucencyGIGridZParams.y) * TranslucencyGIGridZParams.z;
return ZSlice;
}
float3 ComputeCellTranslatedWorldPosition(uint3 GridCoordinate, float3 CellOffset, out float SceneDepth)
{
float2 VolumeUV = (GridCoordinate.xy + CellOffset.xy) / TranslucencyGIGridSize.xy;
float2 VolumeNDC = (VolumeUV * 2 - 1) * float2(1, -1);
SceneDepth = ComputeDepthFromZSlice(GridCoordinate.z + CellOffset.z);
float TileDeviceZ = ConvertToDeviceZ(SceneDepth);
float4 CenterPosition = mul(float4(VolumeNDC, TileDeviceZ, 1), UnjitteredClipToTranslatedWorld);
return CenterPosition.xyz / CenterPosition.w;
}
float3 ComputeCellTranslatedWorldPosition(uint3 GridCoordinate, float3 CellOffset)
{
float Unused;
return ComputeCellTranslatedWorldPosition(GridCoordinate, CellOffset, Unused);
}
float3 ComputeCellWorldPosition(uint3 GridCoordinate, float3 CellOffset)
{
return ComputeCellTranslatedWorldPosition(GridCoordinate, CellOffset) - DFHackToFloat(PrimaryView.PreViewTranslation);
}
float3 ComputeTranslucencyGIVolumeUV(float3 WorldPosition, float4x4 WorldToClip)
{
float4 NDCPosition = mul(float4(WorldPosition, 1), WorldToClip);
NDCPosition.xy /= NDCPosition.w;
float NormalizedZSlice = log2(NDCPosition.w * TranslucencyGIGridZParams.x + TranslucencyGIGridZParams.y) * TranslucencyGIGridZParams.z / (float)TranslucencyGIGridSize.z;
return float3(NDCPosition.xy * float2(.5f, -.5f) + .5f, NormalizedZSlice);
}
void GetProbeTracingUV(
float2 TracingTexelCoord,
float2 ProbeTexelCenter,
out float2 ProbeUV,
out float ConeHalfAngle)
{
ProbeUV = (TracingTexelCoord + ProbeTexelCenter) / float(TranslucencyVolumeTracingOctahedronResolution);
// Evenly distributing the sphere solid angle among all cones
ConeHalfAngle = acosFast(1.0f - 1.0f / (float)(TranslucencyVolumeTracingOctahedronResolution * TranslucencyVolumeTracingOctahedronResolution));
}
float2 GetProbeTexelCenter(uint2 GridCoordinate)
{
return BlueNoiseVec2(GridCoordinate, FroxelDirectionJitterFrameIndex < 0 ? 0 : FroxelDirectionJitterFrameIndex);
}
float HZBMipLevel;
float GetMaxVisibleDepth(uint2 GridCoordinate)
{
float2 HZBScreenUV = (GridCoordinate.xy + .5f) * (1U << TranslucencyGIGridPixelSizeShift) * View.ViewSizeAndInvSize.zw * ViewportUVToHZBBufferUV;
float TrilinearFootprintMipBias = 1.0f;
return ConvertFromDeviceZ(FurthestHZBTexture.SampleLevel(GlobalPointClampedSampler, HZBScreenUV, HZBMipLevel + TrilinearFootprintMipBias).x);
}
bool IsFroxelVisible(uint3 GridCoordinate)
{
#define HZB_OCCLUSION_TEST 1
#if HZB_OCCLUSION_TEST
float MaxVisibleDepth = GetMaxVisibleDepth(GridCoordinate.xy);
float TrilinearFootprintBias = -1.0f;
float FroxelMinSceneDepth = ComputeDepthFromZSlice(max((float)GridCoordinate.z + TrilinearFootprintBias, 0.0f));
return FroxelMinSceneDepth < MaxVisibleDepth;
#else
return true;
#endif
}
float MaxTraceDistance;
float MaxMeshSDFTraceDistance;
float StepFactor;
float VoxelTraceStartDistanceScale;
float MaxRayIntensity;