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

144 lines
4.4 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Common.ush"
#include "SlateShaderCommon.ush"
#include "GammaCorrectionCommon.ush"
#define MAX_SAMPLES 127
// Weigts and offsets are packed into 4 floats (Weight, Offset, Weight, Offset)
float4 WeightAndOffsets[MAX_SAMPLES/2];
/** Blur sample count */
int SampleCount;
Texture2D ElementTexture;
SamplerState ElementTextureSampler;
float4 BufferSizeAndDirection;
float4 UVBounds;
float4 ShaderParams;
float4 ShaderParams2;
float4 GetSample(float Weight, float Offset, float2 UV)
{
const float2 MinUV = UVBounds.xy;
const float2 MaxUV = UVBounds.zw;
const float2 Direction = BufferSizeAndDirection.zw;
const float2 BufferSize = BufferSizeAndDirection.xy;
const float2 UVOffset = float2(Offset*BufferSize.x*Direction.x, Offset*BufferSize.y*Direction.y);
return
Texture2DSample(ElementTexture, ElementTextureSampler, clamp(UV + UVOffset, MinUV, MaxUV)) * Weight
+ Texture2DSample(ElementTexture, ElementTextureSampler, clamp(UV - UVOffset, MinUV, MaxUV)) * Weight;
}
float4 GaussianBlurMain(in noperspective float4 InUVAndScreenPos : TEXCOORD0) : SV_Target0
{
float4 OutColor = Texture2DSample(ElementTexture, ElementTextureSampler, clamp(InUVAndScreenPos.xy, UVBounds.xy, UVBounds.zw)) * WeightAndOffsets[0].x;
// First offset is in zw
{
float Weight = WeightAndOffsets[0].z;
float Offset = WeightAndOffsets[0].w;
OutColor += GetSample(Weight, Offset, InUVAndScreenPos.xy);
}
for (int i = 2; i<SampleCount; i+=2)
{
int Index = i/2;
{
float Weight = WeightAndOffsets[Index].x;
float Offset = WeightAndOffsets[Index].y;
OutColor += GetSample(Weight, Offset, InUVAndScreenPos.xy);
}
{
float Weight = WeightAndOffsets[Index].z;
float Offset = WeightAndOffsets[Index].w;
OutColor += GetSample(Weight, Offset, InUVAndScreenPos.xy);
}
}
return float4(OutColor.rgb, 1);
}
float4 DownsampleMain(in noperspective float4 InUVAndScreenPos : TEXCOORD0) : SV_Target0
{
float2 UV[4];
float2 MinUV = UVBounds.xy;
float2 MaxUV = UVBounds.zw;
// Shader params X/Y stores the UV offset in each direction
UV[0] = clamp(InUVAndScreenPos.xy + ShaderParams.xy * float2(-1, -1), MinUV, MaxUV);
UV[1] = clamp(InUVAndScreenPos.xy + ShaderParams.xy * float2(1, -1), MinUV, MaxUV);
UV[2] = clamp(InUVAndScreenPos.xy + ShaderParams.xy * float2(-1, 1), MinUV, MaxUV);
UV[3] = clamp(InUVAndScreenPos.xy + ShaderParams.xy * float2(1, 1), MinUV, MaxUV);
float4 Sample[4];
UNROLL for(int i = 0; i < 4; ++i)
{
Sample[i] = Texture2DSample(ElementTexture, ElementTextureSampler, UV[i]);
}
return float4(Sample[0] + Sample[1] + Sample[2] + Sample[3]) * 0.25f;
}
float2 Map(float2 value, float2 min1, float2 max1, float2 min2, float2 max2)
{
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}
#define UPSAMPLE_OUTPUT_FORMAT_SDR 0
#define UPSAMPLE_OUTPUT_FORMAT_HDR_SCRGB 1
#define UPSAMPLE_OUTPUT_FORMAT_HDR_PQ10 2
void UpsampleMain(in noperspective float4 InUVAndScreenPos : TEXCOORD0
, out float4 Color0 : SV_Target0
#if UPSAMPLE_OUTPUT_FORMAT != UPSAMPLE_OUTPUT_FORMAT_SDR
, out float4 Color1 : SV_Target1
#endif
)
{
const float2 LocalSize = ShaderParams.xy;
const float2 UV = InUVAndScreenPos.xy;
const float Thickness = 0;
const float4 CornerRadii = ShaderParams2;
const float4 FillColor = Texture2DSample(ElementTexture, ElementTextureSampler, UV);
Color0 = GetRoundedBoxElementColorInternal(LocalSize, Map(UV, float2(0,0), ShaderParams.zw, float2(0,0),float2(1,1)), Thickness, CornerRadii, FillColor, FillColor);
#if UPSAMPLE_OUTPUT_FORMAT != UPSAMPLE_OUTPUT_FORMAT_SDR
static const float3x3 XYZ_2_sRGB_MAT =
{
3.2409699419, -1.5373831776, -0.4986107603,
-0.9692436363, 1.8759675015, 0.0415550574,
0.0556300797, -0.2039769589, 1.0569715142,
};
static const float3x3 Rec2020_2_XYZ_MAT =
{
0.6369736, 0.1446172, 0.1688585,
0.2627066, 0.6779996, 0.0592938,
0.0000000, 0.0280728, 1.0608437
};
static const float ScRGBScaleFactor = 80.0f; // used to convert between ScRGB and nits
Color0.xyz *= ScRGBScaleFactor;
#if UPSAMPLE_OUTPUT_FORMAT == UPSAMPLE_OUTPUT_FORMAT_HDR_SCRGB
const float3x3 Rec2020_2_sRGB = mul(XYZ_2_sRGB_MAT, Rec2020_2_XYZ_MAT);
Color0.xyz = mul(Rec2020_2_sRGB, Color0.xyz) / ScRGBScaleFactor;
#else
Color0.xyz = LinearToST2084(Color0.xyz);
#endif
// Erase the data that was previously in the UI now that the background blur is done
Color1 = float4(0, 0, 0, 0);
#endif
}