Skip to content

Commit efcb909

Browse files
committed
optimize TMPFont
1 parent 17a3a13 commit efcb909

File tree

2 files changed

+103
-81
lines changed

2 files changed

+103
-81
lines changed

Assets/Scripts/Core/Text/FontManager.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,6 @@ static public BaseFont GetFont(string name)
9797
font.name = name;
9898
sFontFactory.Add(name, font);
9999
((TMPFont)font).fontAsset = (TMPro.TMP_FontAsset)asset;
100-
101-
if (!_checkTextMeshPro)
102-
{
103-
_checkTextMeshPro = true;
104-
if (ShaderConfig.Get("TextMeshPro/Distance Field") == null)
105-
Debug.LogWarning("Missing TMP_SDF.shader, please import the TMP essential resources.");
106-
}
107100
}
108101
#endif
109102
else

Assets/Scripts/Extensions/TextMeshPro/TMPFont.cs

Lines changed: 103 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@ public class TMPFont : BaseFont
2828
TextFormat _format;
2929
TMP_Character _char;
3030
TMP_Character _lineChar;
31-
Material _material;
3231
MaterialManager _manager;
3332

33+
float _gradientScale;
34+
float _ratioA;
35+
float _ratioB;
36+
float _ratioC;
37+
3438
public TMPFont()
3539
{
3640
this.canTint = true;
@@ -74,12 +78,6 @@ void Release()
7478
mainTexture.Dispose();
7579
mainTexture = null;
7680
}
77-
78-
if (_material != null)
79-
{
80-
Material.DestroyImmediate(_material);
81-
_material = null;
82-
}
8381
}
8482

8583
void Init()
@@ -92,17 +90,11 @@ void Init()
9290
_manager = mainTexture.GetMaterialManager(this.shader);
9391
_manager.onCreateNewMaterial += OnCreateNewMaterial;
9492

95-
_material = new Material(_fontAsset.material); //copy
96-
_material.SetFloat(ShaderUtilities.ID_TextureWidth, mainTexture.width);
97-
_material.SetFloat(ShaderUtilities.ID_TextureHeight, mainTexture.height);
98-
_material.SetFloat(ShaderUtilities.ID_GradientScale, fontAsset.atlasPadding + 1);
99-
_material.SetFloat(ShaderUtilities.ID_WeightNormal, fontAsset.normalStyle);
100-
_material.SetFloat(ShaderUtilities.ID_WeightBold, fontAsset.boldStyle);
101-
10293
// _ascent = _fontAsset.faceInfo.ascentLine;
10394
// _lineHeight = _fontAsset.faceInfo.lineHeight;
10495
_ascent = _fontAsset.faceInfo.pointSize;
10596
_lineHeight = _fontAsset.faceInfo.pointSize * 1.25f;
97+
_gradientScale = fontAsset.atlasPadding + 1;
10698

10799
_lineChar = GetCharacterFromFontAsset('_', FontStyles.Normal);
108100
}
@@ -111,34 +103,42 @@ void OnCreateNewMaterial(Material mat)
111103
{
112104
mat.SetFloat(ShaderUtilities.ID_TextureWidth, mainTexture.width);
113105
mat.SetFloat(ShaderUtilities.ID_TextureHeight, mainTexture.height);
114-
mat.SetFloat(ShaderUtilities.ID_GradientScale, fontAsset.atlasPadding + 1);
106+
mat.SetFloat(ShaderUtilities.ID_GradientScale, _gradientScale);
115107
mat.SetFloat(ShaderUtilities.ID_WeightNormal, fontAsset.normalStyle);
116108
mat.SetFloat(ShaderUtilities.ID_WeightBold, fontAsset.boldStyle);
117109
}
118110

119111
override public void UpdateGraphics(NGraphics graphics)
120112
{
121113
MaterialPropertyBlock block = graphics.materialPropertyBlock;
114+
115+
UpdateShaderRatios();
116+
_padding = GetPadding();
117+
118+
block.SetFloat(ShaderUtilities.ID_ScaleRatio_A, _ratioA);
119+
block.SetFloat(ShaderUtilities.ID_ScaleRatio_B, _ratioB);
120+
block.SetFloat(ShaderUtilities.ID_ScaleRatio_C, _ratioC);
121+
122+
block.SetFloat(ShaderUtilities.ID_FaceDilate, _format.faceDilate);
123+
block.SetFloat(ShaderUtilities.ID_OutlineSoftness, _format.outlineSoftness);
124+
122125
if (_format.outline > 0)
123126
{
124127
graphics.ToggleKeyword("OUTLINE_ON", true);
125-
_material.EnableKeyword("OUTLINE_ON");
126128

127129
block.SetFloat(ShaderUtilities.ID_OutlineWidth, _format.outline);
128130
block.SetColor(ShaderUtilities.ID_OutlineColor, _format.outlineColor);
129131
}
130132
else
131133
{
132134
graphics.ToggleKeyword("OUTLINE_ON", false);
133-
_material.DisableKeyword("OUTLINE_ON");
134135

135136
block.SetFloat(ShaderUtilities.ID_OutlineWidth, 0);
136137
}
137138

138139
if (_format.shadowOffset.x != 0 || _format.shadowOffset.y != 0)
139140
{
140141
graphics.ToggleKeyword("UNDERLAY_ON", true);
141-
_material.EnableKeyword("UNDERLAY_ON");
142142

143143
block.SetColor(ShaderUtilities.ID_UnderlayColor, _format.shadowColor);
144144
block.SetFloat(ShaderUtilities.ID_UnderlayOffsetX, _format.shadowOffset.x);
@@ -148,78 +148,31 @@ override public void UpdateGraphics(NGraphics graphics)
148148
else
149149
{
150150
graphics.ToggleKeyword("UNDERLAY_ON", false);
151-
_material.DisableKeyword("UNDERLAY_ON");
152151

153152
block.SetFloat(ShaderUtilities.ID_UnderlayOffsetX, 0);
154153
block.SetFloat(ShaderUtilities.ID_UnderlayOffsetY, 0);
155154
block.SetFloat(ShaderUtilities.ID_UnderlaySoftness, 0);
156155
}
157156

158-
block.SetFloat(ShaderUtilities.ID_FaceDilate, _format.faceDilate);
159-
block.SetFloat(ShaderUtilities.ID_OutlineSoftness, _format.outlineSoftness);
157+
_stylePadding = (((_style & FontStyles.Bold) == FontStyles.Bold) ? _fontAsset.boldStyle : _fontAsset.normalStyle)
158+
/ 4.0f * _gradientScale * _ratioA;
160159

161-
if (_material.HasProperty(ShaderUtilities.ID_ScaleRatio_A))
162-
{
163-
//ShaderUtilities.GetPadding does not support handle materialproperyblock, we have to use a temp material
164-
_material.SetFloat(ShaderUtilities.ID_OutlineWidth, block.GetFloat(ShaderUtilities.ID_OutlineWidth));
165-
_material.SetFloat(ShaderUtilities.ID_UnderlayOffsetX, block.GetFloat(ShaderUtilities.ID_UnderlayOffsetX));
166-
_material.SetFloat(ShaderUtilities.ID_UnderlayOffsetY, block.GetFloat(ShaderUtilities.ID_UnderlayOffsetY));
167-
_material.SetFloat(ShaderUtilities.ID_UnderlaySoftness, block.GetFloat(ShaderUtilities.ID_UnderlaySoftness));
168-
_material.SetFloat(ShaderUtilities.ID_FaceDilate, block.GetFloat(ShaderUtilities.ID_FaceDilate));
169-
_material.SetFloat(ShaderUtilities.ID_OutlineSoftness, block.GetFloat(ShaderUtilities.ID_OutlineSoftness));
170-
171-
_padding = ShaderUtilities.GetPadding(_material, false, false);
172-
173-
//and then set back the properteis
174-
block.SetFloat(ShaderUtilities.ID_ScaleRatio_A, _material.GetFloat(ShaderUtilities.ID_ScaleRatio_A));
175-
block.SetFloat(ShaderUtilities.ID_ScaleRatio_B, _material.GetFloat(ShaderUtilities.ID_ScaleRatio_B));
176-
block.SetFloat(ShaderUtilities.ID_ScaleRatio_C, _material.GetFloat(ShaderUtilities.ID_ScaleRatio_C));
177-
}
178-
179-
// Set Padding based on selected font style
180-
#region Handle Style Padding
181-
if (((_style & FontStyles.Bold) == FontStyles.Bold)) // Checks for any combination of Bold Style.
182-
{
183-
if (_material.HasProperty(ShaderUtilities.ID_GradientScale))
184-
{
185-
float gradientScale = _material.GetFloat(ShaderUtilities.ID_GradientScale);
186-
_stylePadding = _fontAsset.boldStyle / 4.0f * gradientScale * _material.GetFloat(ShaderUtilities.ID_ScaleRatio_A);
187-
188-
// Clamp overall padding to Gradient Scale size.
189-
if (_stylePadding + _padding > gradientScale)
190-
_padding = gradientScale - _stylePadding;
191-
}
192-
else
193-
_stylePadding = 0;
194-
}
195-
else
196-
{
197-
if (_material.HasProperty(ShaderUtilities.ID_GradientScale))
198-
{
199-
float gradientScale = _material.GetFloat(ShaderUtilities.ID_GradientScale);
200-
_stylePadding = _fontAsset.normalStyle / 4.0f * gradientScale * _material.GetFloat(ShaderUtilities.ID_ScaleRatio_A);
201-
202-
// Clamp overall padding to Gradient Scale size.
203-
if (_stylePadding + _padding > gradientScale)
204-
_padding = gradientScale - _stylePadding;
205-
}
206-
else
207-
_stylePadding = 0;
208-
}
209-
#endregion Handle Style Padding
160+
// Clamp overall padding to Gradient Scale size.
161+
if (_stylePadding + _padding > _gradientScale)
162+
_padding = _gradientScale - _stylePadding;
210163
}
211164

212165
override public void SetFormat(TextFormat format, float fontSizeScale)
213166
{
214167
_format = format;
215168

216-
float size = format.size * fontSizeScale;
169+
float size = _format.size * fontSizeScale;
217170
if (_format.specialStyle == TextFormat.SpecialStyle.Subscript || _format.specialStyle == TextFormat.SpecialStyle.Superscript)
218171
size *= SupScale;
219172

220173
_scale = size / _fontAsset.faceInfo.pointSize * _fontAsset.faceInfo.scale;
221174
_style = FontStyles.Normal;
222-
if (format.bold)
175+
if (_format.bold)
223176
{
224177
_style |= FontStyles.Bold;
225178
_fontWeight = FontWeight.Bold;
@@ -230,10 +183,10 @@ override public void SetFormat(TextFormat format, float fontSizeScale)
230183
_fontWeight = _defaultFontWeight;
231184
_boldMultiplier = 1.0f;
232185
}
233-
if (format.italic)
186+
if (_format.italic)
234187
_style |= FontStyles.Italic;
235188

236-
format.FillVertexColors(vertexColors);
189+
_format.FillVertexColors(vertexColors);
237190
}
238191

239192
override public bool GetGlyph(char ch, out float width, out float height, out float baseline)
@@ -540,6 +493,82 @@ override public int GetLineHeight(int size)
540493
{
541494
return Mathf.RoundToInt(_lineHeight * ((float)size / _fontAsset.faceInfo.pointSize * _fontAsset.faceInfo.scale));
542495
}
496+
497+
float GetPadding()
498+
{
499+
Vector4 padding = Vector4.zero;
500+
Vector4 maxPadding = Vector4.zero;
501+
502+
float faceDilate = _format.faceDilate * _ratioA;
503+
float faceSoftness = _format.outlineSoftness * _ratioA;
504+
float outlineThickness = _format.outline * _ratioA;
505+
506+
float uniformPadding = outlineThickness + faceSoftness + faceDilate;
507+
508+
// Underlay padding contribution
509+
if (_format.shadowOffset.x != 0 || _format.shadowOffset.y != 0)
510+
{
511+
float offsetX = _format.shadowOffset.x * _ratioC;
512+
float offsetY = -_format.shadowOffset.y * _ratioC;
513+
float dilate = _format.faceDilate * _ratioC;
514+
float softness = _format.underlaySoftness * _ratioC;
515+
516+
padding.x = Mathf.Max(padding.x, faceDilate + dilate + softness - offsetX);
517+
padding.y = Mathf.Max(padding.y, faceDilate + dilate + softness - offsetY);
518+
padding.z = Mathf.Max(padding.z, faceDilate + dilate + softness + offsetX);
519+
padding.w = Mathf.Max(padding.w, faceDilate + dilate + softness + offsetY);
520+
}
521+
522+
padding.x = Mathf.Max(padding.x, uniformPadding);
523+
padding.y = Mathf.Max(padding.y, uniformPadding);
524+
padding.z = Mathf.Max(padding.z, uniformPadding);
525+
padding.w = Mathf.Max(padding.w, uniformPadding);
526+
527+
padding.x = Mathf.Min(padding.x, 1);
528+
padding.y = Mathf.Min(padding.y, 1);
529+
padding.z = Mathf.Min(padding.z, 1);
530+
padding.w = Mathf.Min(padding.w, 1);
531+
532+
maxPadding.x = maxPadding.x < padding.x ? padding.x : maxPadding.x;
533+
maxPadding.y = maxPadding.y < padding.y ? padding.y : maxPadding.y;
534+
maxPadding.z = maxPadding.z < padding.z ? padding.z : maxPadding.z;
535+
maxPadding.w = maxPadding.w < padding.w ? padding.w : maxPadding.w;
536+
537+
padding *= _gradientScale;
538+
539+
// Set UniformPadding to the maximum value of any of its components.
540+
uniformPadding = Mathf.Max(padding.x, padding.y);
541+
uniformPadding = Mathf.Max(padding.z, uniformPadding);
542+
uniformPadding = Mathf.Max(padding.w, uniformPadding);
543+
544+
return uniformPadding + 1.25f;
545+
}
546+
547+
// Scale Ratios to ensure property ranges are optimum in Material Editor
548+
void UpdateShaderRatios()
549+
{
550+
_ratioA = _ratioB = _ratioC = 1;
551+
552+
bool isRatioEnabled = true;
553+
float clamp = 1;
554+
555+
float weight = Mathf.Max(fontAsset.normalStyle, fontAsset.boldStyle) / 4.0f;
556+
float range = (weight + _format.faceDilate) * (_gradientScale - clamp);
557+
558+
// Compute Ratio A
559+
float t = Mathf.Max(1, weight + _format.faceDilate + _format.outline + _format.outlineSoftness);
560+
_ratioA = isRatioEnabled ? (_gradientScale - clamp) / (_gradientScale * t) : 1;
561+
562+
// Compute Ratio B
563+
// no glow support yet
564+
565+
// Compute Ratio C
566+
if (_format.shadowOffset.x != 0 || _format.shadowOffset.y != 0)
567+
{
568+
t = Mathf.Max(1, Mathf.Max(Mathf.Abs(_format.shadowOffset.x), Mathf.Abs(-_format.shadowOffset.y)) + _format.faceDilate + _format.underlaySoftness);
569+
_ratioC = isRatioEnabled ? Mathf.Max(0, _gradientScale - clamp - range) / (_gradientScale * t) : 1;
570+
}
571+
}
543572
}
544573
}
545574

0 commit comments

Comments
 (0)