113 lines
4.0 KiB
HLSL
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;
|