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

119 lines
3.9 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
/** Shader types (mirrored from ESlateShader::Type in RenderingCommon.h */
#define ST_Default 0
#define ST_Border 1
#define ST_GrayscaleFont 2
#define ST_ColorFont 3
#define ST_LineSegment 4
#define ST_Custom 5
#define ST_PostProcess 6
#define ST_RoundedBox 7
#define ST_SdfFont 8
#define ST_MsdfFont 9
#if USE_MATERIALS
#include "/Engine/Generated/Material.ush"
#if NUM_MATERIAL_TEXCOORDS
#define NUM_SLATE_TEXCOORDS NUM_MATERIAL_TEXCOORDS
#else
#define NUM_SLATE_TEXCOORDS 1
#endif // NUM_MATERIAL_TEXCOORDS
#define HAS_MATERIAL_TEXCOORDS NUM_MATERIAL_TEXCOORDS > 0
#else
#define HAS_MATERIAL_TEXCOORDS 0
// This is defined automatically based on the number of textures in a material
// In the case that this is a basic texture lookup shader, we only need 1 uv set
#define NUM_SLATE_TEXCOORDS 1
#endif
#define SOURCE_IN_LINEAR_SPACE 1
struct VertexToPixelInterpolants
{
float4 Position : SV_POSITION;
half4 Color : COLOR0;
half4 SecondaryColor : COLOR1;
float4 OriginalPosition : ORIGINAL_POSITION;
float2 MaterialTexCoords : TEXCOORD0;
float4 TextureCoordinates0 : TEXCOORD1;
#if NUM_SLATE_TEXCOORDS > 2
float4 TextureCoordinates1 : TEXCOORD2;
#endif
#if NUM_SLATE_TEXCOORDS > 4
float4 TextureCoordinates2 : TEXCOORD3;
#endif
#if NUM_SLATE_TEXCOORDS > 6
float4 TextureCoordinates3 : TEXCOORD4;
#endif
};
#define SLATE_UV0(Interpolants) Interpolants.TextureCoordinates0.xy
#define SLATE_UV1(Interpolants) Interpolants.TextureCoordinates0.zw
#define SLATE_UV2(Interpolants) Interpolants.TextureCoordinates1.xy
#define SLATE_UV3(Interpolants) Interpolants.TextureCoordinates1.zw
#define SLATE_UV4(Interpolants) Interpolants.TextureCoordinates2.xy
#define SLATE_UV5(Interpolants) Interpolants.TextureCoordinates2.zw
#define SLATE_UV6(Interpolants) Interpolants.TextureCoordinates3.xy
#define SLATE_UV7(Interpolants) Interpolants.TextureCoordinates3.zw
float cross(float2 a, float2 b)
{
return a.x*b.y - a.y*b.x;
}
float GetRoundedBoxDistance(float2 pos, float2 center, float radius, float inset)
{
// distance from center
pos = abs(pos - center);
// distance from the inner corner
pos = pos - (center - float2(radius + inset, radius + inset));
// use distance to nearest edge when not in quadrant with radius
// this handles an edge case when radius is very close to thickness
// otherwise we're in the quadrant with the radius,
// just use the analytic signed distance function
return lerp( length(pos) - radius, max(pos.x - radius, pos.y - radius), float(pos.x <= 0 || pos.y <=0) );
}
float4 GetRoundedBoxElementColorInternal(float2 size, float2 UV, float thickness, float4 cornerRadii, float4 fillColor, float4 borderColor)
{
float2 pos = size * UV;
float2 center = size / 2.0;
//cornerRadii: X = Top Left, Y = Top Right, Z = Bottom Right, W = Bottom Left */
// figure out which radius to use based on which quadrant we're in
float2 quadrant = step(UV, float2(.5,.5));
float left = lerp(cornerRadii.y, cornerRadii.x, quadrant.x);
float right = lerp(cornerRadii.z, cornerRadii.w, quadrant.x);
float radius = lerp(right, left, quadrant.y);
// Compute the distances internal and external to the border outline
float dext = GetRoundedBoxDistance(pos, center, radius, 0.0);
float din = GetRoundedBoxDistance(pos, center, max(radius - thickness, 0), thickness);
// Compute the border intensity and fill intensity with a smooth transition
float bi_spread = 1.0;
float bi = smoothstep(bi_spread, -bi_spread, dext);
float fi_spread = .5;
float fi = smoothstep(fi_spread, -fi_spread, din);
float4 fill = fillColor;
float4 border = borderColor;
// alpha blend the external color
float4 OutColor = lerp(border, fill, float(thickness > radius));
OutColor.a = 0.0;
// blend in the border and fill colors
OutColor = lerp(OutColor, border, bi);
OutColor = lerp(OutColor, fill, fi);
return OutColor;
}