-
-
Notifications
You must be signed in to change notification settings - Fork 962
/
Copy pathSignedDistanceFieldFont.sdsl
48 lines (37 loc) · 1.94 KB
/
SignedDistanceFieldFont.sdsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
shader SignedDistanceFieldFont : Texturing
{
// Gets the median of 3 values
float median(float r, float g, float b)
{
return max(min(r, g), min(max(r, g), b));
}
// Retrieves the pixel's color sampled from a signed distance field font texture, with font color, border and shadows
stage float4 FontColor(float4 sampledColor, float4 textColor, float4 borderColor, float borderThickness)
{
// -0.5 to +0.5 is the maximum distance msdfgen can produce, but it's blurry so cap the border at 0.25
borderThickness = clamp(borderThickness, 0, 0.2);
// Higher (more than 1) - sharper
// Lower (less than 1, more than 0) - blurry
float sharpnessMagnitude = 0.5f;
float axisDistance = 0.4 - borderThickness;
// Get the median distance encoded in the signed distance field
float medianDistance = median(sampledColor.r, sampledColor.g, sampledColor.b);
float sigDist = medianDistance - axisDistance;
float transition = fwidth(sigDist) * 0.85;
float opacity = smoothstep(-transition, transition, sigDist);
opacity *= opacity;
// Detect edge
if (borderThickness > 0)
{
float farDistance = axisDistance + borderThickness * 2;
float sigDistBorder = medianDistance - farDistance;
float borderLine = sharpnessMagnitude * sigDistBorder/fwidth(sigDistBorder) + farDistance;
float borderOpacity = smoothstep(0, 1, borderLine);
textColor = lerp(borderColor, textColor, borderOpacity);
}
sampledColor = lerp(float4(0,0,0,0), textColor, opacity);
return sampledColor;
}
};