Files
UnrealEngineUWP/Engine/Shaders/Private/SlatePostProcessPixelShader.usf
benjamin rouveyrol 5fa55f2449 Background blur optimizations (followup of 20933909)
Instead of rendering to an 11-11-10 (in rec2020 space) and keeping a mask, we have the background blur write directly to the swapchain during the up-sample pass.
The 11-11-10 RT is kept but only for the background blur. BlitUIToHDRPS will take care of moving / blending in rec2020 and will output to the 11-11-10 in rec2020, which will be blurred just like in  20933909.
UpsampleMain will then take care of going back to the swapchain color space / format (and still erase the UI in the same region).
A copy of the swapchain will still happen, but right before UI composition. I will then remove that copy in a next CL for platforms that support UAV flag for swapchain.

Fix UpdateScissorRect that would reset rendertarget1 when being called. Use instead the current FRHIRenderPassInfo to keep the same RT layout when updating the stencilbuffer

#preflight 630c62e9660db81edb63918c
#jira UE-81932
#rb daren.cheng

[CL 21670277 by benjamin rouveyrol in ue5-main branch]
2022-08-29 06:00:24 -04:00

163 lines
4.4 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Common.ush"
#include "SlateShaderCommon.ush"
#include "GammaCorrectionCommon.ush"
#define BILINEAR_FILTER_METHOD 1
#define MAX_SAMPLES 127
#if BILINEAR_FILTER_METHOD
// Weigts and offsets are packed into 4 floats (Weight, Offset, Weight, Offset)
float4 WeightAndOffsets[MAX_SAMPLES/2];
#else
#define MAX_SAMPLES 127
// Weigts and offsets are packed into 4 floats (Weight, Offset, Weight, Offset)
float4 WeightAndOffsets[MAX_SAMPLES];
#endif
/** 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( FScreenVertexOutput Input ) : SV_Target0
{
#if 0
float4 OutColor = Texture2DSample(ElementTexture, ElementTextureSampler, Input.UV);
#else
float4 OutColor = Texture2DSample(ElementTexture, ElementTextureSampler, clamp(Input.UV, 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, Input.UV);
}
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, Input.UV);
}
{
float Weight = WeightAndOffsets[Index].z;
float Offset = WeightAndOffsets[Index].w;
OutColor += GetSample(Weight, Offset, Input.UV);
}
}
#endif
return float4(OutColor.rgb, 1);
}
float4 DownsampleMain(FScreenVertexOutput Input) : SV_Target0
{
#if 0
return Texture2DSample(ElementTexture, ElementTextureSampler, Input.UV);
#else
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(Input.UV + ShaderParams.xy * float2(-1, -1), MinUV, MaxUV);
UV[1] = clamp(Input.UV + ShaderParams.xy * float2(1, -1), MinUV, MaxUV);
UV[2] = clamp(Input.UV + ShaderParams.xy * float2(-1, 1), MinUV, MaxUV);
UV[3] = clamp(Input.UV + 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;
#endif
}
float2 Map(float2 value, float2 min1, float2 max1, float2 min2, float2 max2)
{
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}
void UpsampleMain(FScreenVertexOutput Input
, out float4 Color0 : SV_Target0
#if OUTPUT_TO_UI_TARGET
, out float4 Color1 : SV_Target1
#endif
)
{
const float2 LocalSize = ShaderParams.xy;
const float2 UV = Input.UV;
const float Thickness = 0;
const float4 CornerRadii = ShaderParams2;
const float4 FillColor = Texture2DSample(ElementTexture, ElementTextureSampler, Input.UV);
Color0 = GetRoundedBoxElementColorInternal(LocalSize, Map(UV, float2(0,0), ShaderParams.zw, float2(0,0),float2(1,1)), Thickness, CornerRadii, FillColor, FillColor);
#if OUTPUT_TO_UI_TARGET
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 SCRGB_ENCODING
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
}