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

71 lines
2.4 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
SkyLightingShared.usf
=============================================================================*/
#pragma once
float ApproximateConeConeIntersection(float ArcLength0, float ArcLength1, float AngleBetweenCones)
{
float AngleDifference = abs(ArcLength0 - ArcLength1);
float Intersection = smoothstep(
0,
1.0,
1.0 - saturate((AngleBetweenCones - AngleDifference) / (ArcLength0 + ArcLength1 - AngleDifference)));
return Intersection;
}
float ApplyBentNormalAO;
float InvSkySpecularOcclusionStrength;
float4 OcclusionTintAndMinOcclusion;
void GetDistanceFieldAOSpecularOcclusion(float3 BentNormalAO, float3 ReflectionVector, float Roughness, bool bTwoSidedFoliage, out float IndirectSpecularOcclusion, out float IndirectDiffuseOcclusion, out float3 ExtraIndirectSpecular)
{
IndirectSpecularOcclusion = 1;
IndirectDiffuseOcclusion = 1;
ExtraIndirectSpecular = 0;
BRANCH
if (ApplyBentNormalAO > 0)
{
float BentNormalLength = length(BentNormalAO);
BRANCH
if (View.DistanceFieldAOSpecularOcclusionMode == 0)
{
IndirectSpecularOcclusion = BentNormalLength;
}
else
{
BRANCH
if (bTwoSidedFoliage)
{
IndirectSpecularOcclusion = BentNormalLength;
}
else
{
float ReflectionConeAngle = max(Roughness, .1f) * PI;
float UnoccludedAngle = BentNormalLength * PI * InvSkySpecularOcclusionStrength;
float AngleBetween = acos(dot(BentNormalAO, ReflectionVector) / max(BentNormalLength, .001f));
IndirectSpecularOcclusion = ApproximateConeConeIntersection(ReflectionConeAngle, UnoccludedAngle, AngleBetween);
// Can't rely on the direction of the bent normal when close to fully occluded, lerp to shadowed
IndirectSpecularOcclusion = lerp(0, IndirectSpecularOcclusion, saturate((UnoccludedAngle - .1f) / .2f));
}
}
IndirectSpecularOcclusion = lerp(IndirectSpecularOcclusion, 1, OcclusionTintAndMinOcclusion.w);
ExtraIndirectSpecular = (1 - IndirectSpecularOcclusion) * OcclusionTintAndMinOcclusion.xyz;
IndirectDiffuseOcclusion = lerp(BentNormalLength, 1, OcclusionTintAndMinOcclusion.w);
}
}
float GetDynamicSkyIndirectIrradiance(float3 BentNormal, float3 WorldNormal)
{
float SkyVisibility = length(BentNormal);
float3 DiffuseLookup = GetSkySHDiffuse(WorldNormal) * View.SkyLightColor.rgb;
return Luminance(DiffuseLookup) * SkyVisibility;
}