diff --git a/Content/Shaders/GUI.flax b/Content/Shaders/GUI.flax
index 484f09f46..3e0ccc18f 100644
--- a/Content/Shaders/GUI.flax
+++ b/Content/Shaders/GUI.flax
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:551f893b015cd364911270816607651917545c83d28259c918018ff3ffc15937
-size 5333
+oid sha256:b816ba638bc37b8a8288e4c397ff5b708153057650fa6b626a109ba42d189694
+size 4721
diff --git a/Source/Engine/Render2D/FontAsset.h b/Source/Engine/Render2D/FontAsset.h
index c9966c68b..56cc3d655 100644
--- a/Source/Engine/Render2D/FontAsset.h
+++ b/Source/Engine/Render2D/FontAsset.h
@@ -77,7 +77,7 @@ API_ENUM() enum class FontRasterMode : byte
Bitmap,
///
- /// Use the MSDF generator to render font atlases. Need to be rendered with a compatible material.
+ /// Use the Multi-channel Signed Distance Field (MSDF) generator to render font atlases. Need to be rendered with a compatible material.
///
MSDF,
};
@@ -92,7 +92,7 @@ API_STRUCT() struct FontOptions
DECLARE_SCRIPTING_TYPE_MINIMAL(FontOptions);
///
- /// The hinting.
+ /// The font hinting used when rendering characters.
///
API_FIELD() FontHinting Hinting;
@@ -102,7 +102,7 @@ API_STRUCT() struct FontOptions
API_FIELD() FontFlags Flags;
///
- /// The rasterization mode.
+ /// The font rasterization mode.
///
API_FIELD() FontRasterMode RasterMode;
};
diff --git a/Source/Shaders/GUI.shader b/Source/Shaders/GUI.shader
index b09a3474d..a8f9452e9 100644
--- a/Source/Shaders/GUI.shader
+++ b/Source/Shaders/GUI.shader
@@ -92,7 +92,7 @@ float4 PS_Font(VS2PS input) : SV_Target0
PerformClipping(input);
float4 color = input.Color;
- color.a *= Image.Sample(SamplerLinearClamp, input.TexCoord).r;
+ color.a *= SampleFont(Image, input.TexCoord);
return color;
}
@@ -102,22 +102,8 @@ float4 PS_FontMSDF(VS2PS input) : SV_Target0
PerformClipping(input);
float4 color = input.Color;
- float3 msd = Image.Sample(SamplerLinearClamp, input.TexCoord).rgb;
- float sd = max(min(msd.r, msd.g), min(max(msd.r, msd.g), msd.b));
-
- uint width, height;
- Image.GetDimensions(width, height);
- float pxRange = 4.0f; // Must match C++ code
- float unitRange = float2(pxRange, pxRange) / float2(width, height);
-
- float2 dx = ddx(input.TexCoord);
- float2 dy = ddy(input.TexCoord);
- float2 screenTexSize = rsqrt(dx * dx + dy * dy);
- float screenPxRange = max(0.5f * dot(screenTexSize, unitRange), 1.0f);
- float screenPxDist = screenPxRange * (sd - 0.5f);
-
- float opacity = saturate(screenPxDist + 0.5f);
- return float4(color.rgb, opacity);
+ color.a *= SampleFontMSDF(Image, input.TexCoord);
+ return color;
}
float4 GetSample(float weight, float offset, float2 uv)
diff --git a/Source/Shaders/GUICommon.hlsl b/Source/Shaders/GUICommon.hlsl
index 14c8b1327..67f9daac4 100644
--- a/Source/Shaders/GUICommon.hlsl
+++ b/Source/Shaders/GUICommon.hlsl
@@ -54,4 +54,47 @@ void PerformClipping(VS2PS input)
PerformClipping(input.ClipOriginAndPos.xy, input.ClipOriginAndPos.zw, input.ClipExtents);
}
+float SampleFont(Texture2D font, float2 uv)
+{
+ return font.Sample(SamplerLinearClamp, uv).r;
+}
+
+float GetFontMSDFMedian(Texture2D font, float2 uv)
+{
+ float4 msd = font.Sample(SamplerLinearClamp, uv);
+ return max(min(msd.r, msd.g), min(max(msd.r, msd.g), msd.b));
+}
+
+float GetFontMSDFPixelRange(Texture2D font, float2 uv)
+{
+ uint width, height;
+ font.GetDimensions(width, height);
+ float pxRange = 4.0f; // Must match C++ code
+ float unitRange = float2(pxRange, pxRange) / float2(width, height);
+
+ float2 dx = ddx(uv);
+ float2 dy = ddy(uv);
+ float2 screenTexSize = rsqrt(dx * dx + dy * dy);
+ return max(0.5f * dot(screenTexSize, unitRange), 1.0f);
+}
+
+float SampleFontMSDF(Texture2D font, float2 uv)
+{
+ float sd = GetFontMSDFMedian(font, uv);
+ float screenPxRange = GetFontMSDFPixelRange(font, uv);
+ float screenPxDist = screenPxRange * (sd - 0.5f);
+ return saturate(screenPxDist + 0.5f);
+}
+
+float SampleFontMSDFOutline(Texture2D font, float2 uv, float thickness)
+{
+ float4 msd = font.Sample(SamplerLinearClamp, uv);
+ float sd = max(min(msd.r, msd.g), min(max(msd.r, msd.g), msd.b));
+ float screenPxRange = GetFontMSDFPixelRange(font, uv);
+ float thick = clamp(thickness, 0.0, screenPxRange * 0.5 - 1.0) / screenPxRange;
+ float outline = saturate((min(sd, msd.a) - 0.5 + thick) * screenPxRange + 0.5);
+ outline *= 1 - saturate(screenPxRange * (sd - 0.5f) + 0.5f);
+ return outline;
+}
+
#endif