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

129 lines
3.9 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#include "../Common.ush"
#include "../SHCommon.ush"
#include "LumenTracingCommon.ush"
#include "LumenRadianceCacheCommon.ush"
#define VISUALIZE_MODE_RADIANCE 1
#define VISUALIZE_MODE_SKY_VISIBILITY 2
float4 ClipmapCornerTWSAndCellSizeForVisualization;
float VisualizeProbeRadiusScale;
uint ProbeClipmapIndex;
struct FVisualizeRadianceCacheVSToPS
{
nointerpolation float3 ProbeCoord : TEXCOORD0;
nointerpolation float4 CellSphere : TEXCOORD1;
float3 PositionTWS : TEXCOORD2;
};
float3 GetProbeTranslatedWorldPositionForVisualization(uint3 ProbeCoord, uint ProbeIndex)
{
const float3 ClipmapCornerTWS = ClipmapCornerTWSAndCellSizeForVisualization.xyz;
const float CellSize = ClipmapCornerTWSAndCellSizeForVisualization.w;
const float3 CornerTranslatedWorldPosition = ClipmapCornerTWS;
const float3 CornerToProbe = ((ProbeCoord + 0.5f) * CellSize);
return CornerTranslatedWorldPosition + CornerToProbe + ProbeWorldOffset[ProbeIndex].xyz;
}
void VisualizeRadianceCacheVS(
uint VertexId : SV_VertexID,
uint InstanceId : SV_InstanceID,
out FVisualizeRadianceCacheVSToPS Output,
out float4 OutPosition : SV_POSITION
)
{
float VisualizeRadius = VisualizeProbeRadiusScale * GetRadianceProbeClipmapCellSize(ProbeClipmapIndex);
float3 LocalPosition;
LocalPosition.x = VertexId & 0x1 ? 1.0f : -1.0f;
LocalPosition.y = VertexId & 0x2 ? 1.0f : -1.0f;
LocalPosition.z = VertexId & 0x4 ? 1.0f : -1.0f;
LocalPosition *= VisualizeRadius;
uint3 ProbeCoord;
ProbeCoord.x = InstanceId % RadianceProbeClipmapResolution;
ProbeCoord.y = (InstanceId / RadianceProbeClipmapResolution) % RadianceProbeClipmapResolution;
ProbeCoord.z = InstanceId / (RadianceProbeClipmapResolution * RadianceProbeClipmapResolution);
uint ProbeIndex = GetProbeIndexFromIndirectionTexture(ProbeCoord, ProbeClipmapIndex);
float3 ProbeTranslatedWorldCenter = GetProbeTranslatedWorldPositionForVisualization(ProbeCoord, ProbeIndex);
Output.CellSphere.xyz = ProbeTranslatedWorldCenter;
Output.CellSphere.w = VisualizeRadius;
Output.PositionTWS = LocalPosition + ProbeTranslatedWorldCenter;
Output.ProbeCoord = ProbeCoord;
OutPosition = mul(float4(Output.PositionTWS, 1.0f), PrimaryView.TranslatedWorldToClip);
if (ProbeIndex == INVALID_PROBE_INDEX)
{
OutPosition = 0;
}
}
void VisualizeRadianceCachePS(
FVisualizeRadianceCacheVSToPS Input,
out float4 OutColor : SV_Target0
)
{
float3 RayDirection = Input.PositionTWS;
float2 SphereIntersections = RayIntersectSphere(0, RayDirection, Input.CellSphere);
float3 IntersectionPosition = SphereIntersections.x * RayDirection;
clip(SphereIntersections.x);
float3 SphereNormal = normalize(IntersectionPosition - Input.CellSphere.xyz);
uint ProbeIndex = GetProbeIndexFromIndirectionTexture(Input.ProbeCoord, ProbeClipmapIndex);
float3 Lighting = 0.0f;
#if VISUALIZE_MODE == VISUALIZE_MODE_SKY_VISIBILITY
{
FRadianceCacheSample RadianceCacheSample = SampleRadianceCacheProbe(ProbeIndex, SphereNormal, 0);
Lighting = RadianceCacheSample.SkyVisibility;
}
#else // VISUALIZE_MODE == VISUALIZE_MODE_RADIANCE
{
#if RADIANCE_CACHE_IRRADIANCE
{
float Albedo = .3f;
Lighting = SampleIrradianceCacheProbe(ProbeIndex, SphereNormal) * Albedo;
#define DEBUG_VISUALIZE_PROBES_WITH_OFFSETS 0
#if DEBUG_VISUALIZE_PROBES_WITH_OFFSETS
if (ProbeWorldOffset[ProbeIndex].w > 0)
{
Lighting.g += .1f;
}
#endif
#define DEBUG_VISUALIZE_PROBE_OCCLUSION 0
#if DEBUG_VISUALIZE_PROBE_OCCLUSION
Lighting = float3(SampleProbeOcclusion(ProbeIndex, SphereNormal).xxx / 1000.0f);
#endif
}
#else
{
FRadianceCacheSample RadianceCacheSample = SampleRadianceCacheProbe(ProbeIndex, SphereNormal, 0);
RadianceCacheSample = RadianceCacheResolveSky(RadianceCacheSample, SphereNormal);
Lighting = RadianceCacheSample.Radiance;
}
#endif
}
#endif
if (ProbeIndex == INVALID_PROBE_INDEX)
{
Lighting = float3(0, 1000.0f, 0);
}
Lighting *= View.PreExposure;
OutColor = float4(Lighting, 1.0f);
}