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

124 lines
3.6 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "../ReflectionEnvironmentShared.ush"
#include "../HeightFogCommon.ush"
#include "SurfaceCache/LumenSurfaceCacheSampling.ush"
#ifndef ENABLE_DYNAMIC_SKY_LIGHT
#define ENABLE_DYNAMIC_SKY_LIGHT 1
#endif
struct FConeTraceResult
{
float3 Lighting;
float Transparency;
float NumSteps;
float NumOverlaps;
float OpaqueHitDistance;
float ExpandSurfaceAmount;
float3 Debug;
float3 GeometryWorldNormal;
float3 WorldVelocity;
};
float TanConeAngleToRoughness(float TanConeAngle)
{
//@todo DynamicGI - derive roughness from cone angle
return sqrt(saturate(TanConeAngle / (.5f * PI)));
}
float3 EvaluateSkyRadiance(float3 Direction)
{
float3 SkyRadiance = 0.0f;
#if ENABLE_DYNAMIC_SKY_LIGHT
if (ReflectionStruct.SkyLightParameters.y > 0)
{
float SkyAverageBrightness = 1.0f;
float TanConeAngle = 0.0f;
float Roughness = TanConeAngleToRoughness(TanConeAngle);
SkyRadiance = GetSkyLightReflection(Direction, Roughness, SkyAverageBrightness);
}
#endif
return SkyRadiance;
}
void ApplySkylightToTraceResult(float3 ConeDirection, inout FConeTraceResult TraceResult)
{
#if ENABLE_DYNAMIC_SKY_LIGHT
if (ReflectionStruct.SkyLightParameters.y > 0)
{
float SkyAverageBrightness = 1.0f;
float TanConeAngle = 0.0f;
float Roughness = TanConeAngleToRoughness(TanConeAngle);
TraceResult.Lighting += GetSkyLightReflection(ConeDirection, Roughness, SkyAverageBrightness) * TraceResult.Transparency;
}
#endif
}
float3 SkylightLeakingColor;
float ReflectionSkylightLeakingAverageAlbedo;
float SkylightLeakingRoughness;
float InvFullSkylightLeakingDistance;
uint SampleHeightFog;
float CalculateSkylightLeakingDistanceFactor(float HitDistance)
{
return saturate(HitDistance * InvFullSkylightLeakingDistance);
}
float3 GetSkylightLeaking(float3 ConeDirection, float HitDistance)
{
float3 Lighting = 0;
if (ReflectionStruct.SkyLightParameters.y > 0 && any(SkylightLeakingColor > 0.0f))
{
float SkyAverageBrightness = 1.0f;
Lighting = GetSkyLightReflection(ConeDirection, SkylightLeakingRoughness, SkyAverageBrightness) * SkylightLeakingColor * CalculateSkylightLeakingDistanceFactor(HitDistance);
}
return Lighting;
}
// Reflections should look exactly like primary view.
// In order to achieve that, Skylight leaking approximates GetSkylightLeaking for the hit point.
float3 GetSkylightLeakingForReflections(float3 ConeDirection, float3 HitNormal, float HitDistance)
{
float3 Lighting = 0;
float3 SkylightLeakingMult = View.SkyLightColor.rgb * SkylightLeakingColor * ReflectionSkylightLeakingAverageAlbedo;
if (and(ReflectionStruct.SkyLightParameters.y > 0.0f, any(SkylightLeakingMult > 0.0f)))
{
Lighting = GetSkySHDiffuse(HitNormal) * SkylightLeakingMult;
}
return Lighting;
}
float3 ClampMaxRayIntensity(float3 Radiance, float MaxRayIntensity)
{
float MaxLighting = max3(Radiance.x, Radiance.y, Radiance.z);
if (MaxLighting > MaxRayIntensity * View.OneOverPreExposure)
{
Radiance *= MaxRayIntensity * View.OneOverPreExposure / MaxLighting;
}
return Radiance;
}
float3 GetFogOnLuminance(in float3 SurfaceLuminance, in float SurfaceCoverage, in float3 RayOrigin, in float3 RayDir, in float HitPosDistance)
{
const float ExcludeDistance = 0.0f;
// We override the fog integration origin to match the traced ray.
bool bOverrideOrigin = true;
float4 HeightFogInscatteringAndTransmittance = GetExponentialHeightFog(0, ExcludeDistance, 0, GetPrimaryView(), bOverrideOrigin, RayOrigin, RayDir, HitPosDistance);
HeightFogInscatteringAndTransmittance.rgb *= View.PreExposure;
return SurfaceLuminance * HeightFogInscatteringAndTransmittance.a + HeightFogInscatteringAndTransmittance.rgb * SurfaceCoverage;
}