No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TMP_ShaderUtilities.cs 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. using UnityEngine;
  2. using System.Linq;
  3. using System.Collections;
  4. namespace TMPro
  5. {
  6. public static class ShaderUtilities
  7. {
  8. // Shader Property IDs
  9. public static int ID_MainTex;
  10. public static int ID_FaceTex;
  11. public static int ID_FaceColor;
  12. public static int ID_FaceDilate;
  13. public static int ID_Shininess;
  14. /// <summary>
  15. /// Property ID for the _OutlineOffset1 shader property used by URP and HDRP shaders
  16. /// </summary>
  17. public static int ID_OutlineOffset1;
  18. /// <summary>
  19. /// Property ID for the _OutlineOffset2 shader property used by URP and HDRP shaders
  20. /// </summary>
  21. public static int ID_OutlineOffset2;
  22. /// <summary>
  23. /// Property ID for the _OutlineOffset3 shader property used by URP and HDRP shaders
  24. /// </summary>
  25. public static int ID_OutlineOffset3;
  26. /// <summary>
  27. /// Property ID for the ID_AdditiveOutlineMode shader property used by URP and HDRP shaders
  28. /// </summary>
  29. public static int ID_OutlineMode;
  30. /// <summary>
  31. /// Property ID for the _IsoPerimeter shader property used by URP and HDRP shaders
  32. /// </summary>
  33. public static int ID_IsoPerimeter;
  34. /// <summary>
  35. /// Property ID for the _Softness shader property used by URP and HDRP shaders
  36. /// </summary>
  37. public static int ID_Softness;
  38. public static int ID_UnderlayColor;
  39. public static int ID_UnderlayOffsetX;
  40. public static int ID_UnderlayOffsetY;
  41. public static int ID_UnderlayDilate;
  42. public static int ID_UnderlaySoftness;
  43. /// <summary>
  44. /// Property ID for the _UnderlayOffset shader property used by URP and HDRP shaders
  45. /// </summary>
  46. public static int ID_UnderlayOffset;
  47. /// <summary>
  48. /// Property ID for the _UnderlayIsoPerimeter shader property used by URP and HDRP shaders
  49. /// </summary>
  50. public static int ID_UnderlayIsoPerimeter;
  51. public static int ID_WeightNormal;
  52. public static int ID_WeightBold;
  53. public static int ID_OutlineTex;
  54. public static int ID_OutlineWidth;
  55. public static int ID_OutlineSoftness;
  56. public static int ID_OutlineColor;
  57. public static int ID_Outline2Color;
  58. public static int ID_Outline2Width;
  59. public static int ID_Padding;
  60. public static int ID_GradientScale;
  61. public static int ID_ScaleX;
  62. public static int ID_ScaleY;
  63. public static int ID_PerspectiveFilter;
  64. public static int ID_Sharpness;
  65. public static int ID_TextureWidth;
  66. public static int ID_TextureHeight;
  67. public static int ID_BevelAmount;
  68. public static int ID_GlowColor;
  69. public static int ID_GlowOffset;
  70. public static int ID_GlowPower;
  71. public static int ID_GlowOuter;
  72. public static int ID_GlowInner;
  73. public static int ID_LightAngle;
  74. public static int ID_EnvMap;
  75. public static int ID_EnvMatrix;
  76. public static int ID_EnvMatrixRotation;
  77. //public static int ID_MaskID;
  78. public static int ID_MaskCoord;
  79. public static int ID_ClipRect;
  80. public static int ID_MaskSoftnessX;
  81. public static int ID_MaskSoftnessY;
  82. public static int ID_VertexOffsetX;
  83. public static int ID_VertexOffsetY;
  84. public static int ID_UseClipRect;
  85. public static int ID_StencilID;
  86. public static int ID_StencilOp;
  87. public static int ID_StencilComp;
  88. public static int ID_StencilReadMask;
  89. public static int ID_StencilWriteMask;
  90. public static int ID_ShaderFlags;
  91. public static int ID_ScaleRatio_A;
  92. public static int ID_ScaleRatio_B;
  93. public static int ID_ScaleRatio_C;
  94. public static string Keyword_Bevel = "BEVEL_ON";
  95. public static string Keyword_Glow = "GLOW_ON";
  96. public static string Keyword_Underlay = "UNDERLAY_ON";
  97. public static string Keyword_Ratios = "RATIOS_OFF";
  98. //public static string Keyword_MASK_OFF = "MASK_OFF";
  99. public static string Keyword_MASK_SOFT = "MASK_SOFT";
  100. public static string Keyword_MASK_HARD = "MASK_HARD";
  101. public static string Keyword_MASK_TEX = "MASK_TEX";
  102. public static string Keyword_Outline = "OUTLINE_ON";
  103. public static string ShaderTag_ZTestMode = "unity_GUIZTestMode";
  104. public static string ShaderTag_CullMode = "_CullMode";
  105. private static float m_clamp = 1.0f;
  106. public static bool isInitialized = false;
  107. /// <summary>
  108. /// Returns a reference to the mobile distance field shader.
  109. /// </summary>
  110. internal static Shader ShaderRef_MobileSDF
  111. {
  112. get
  113. {
  114. if (k_ShaderRef_MobileSDF == null)
  115. k_ShaderRef_MobileSDF = Shader.Find("TextMeshPro/Mobile/Distance Field");
  116. return k_ShaderRef_MobileSDF;
  117. }
  118. }
  119. static Shader k_ShaderRef_MobileSDF;
  120. /// <summary>
  121. /// Returns a reference to the mobile bitmap shader.
  122. /// </summary>
  123. internal static Shader ShaderRef_MobileBitmap
  124. {
  125. get
  126. {
  127. if (k_ShaderRef_MobileBitmap == null)
  128. k_ShaderRef_MobileBitmap = Shader.Find("TextMeshPro/Mobile/Bitmap");
  129. return k_ShaderRef_MobileBitmap;
  130. }
  131. }
  132. static Shader k_ShaderRef_MobileBitmap;
  133. /// <summary>
  134. ///
  135. /// </summary>
  136. static ShaderUtilities()
  137. {
  138. GetShaderPropertyIDs();
  139. }
  140. /// <summary>
  141. ///
  142. /// </summary>
  143. public static void GetShaderPropertyIDs()
  144. {
  145. if (isInitialized == false)
  146. {
  147. //Debug.Log("Getting Shader property IDs");
  148. isInitialized = true;
  149. ID_MainTex = Shader.PropertyToID("_MainTex");
  150. ID_FaceTex = Shader.PropertyToID("_FaceTex");
  151. ID_FaceColor = Shader.PropertyToID("_FaceColor");
  152. ID_FaceDilate = Shader.PropertyToID("_FaceDilate");
  153. ID_Shininess = Shader.PropertyToID("_FaceShininess");
  154. ID_OutlineOffset1 = Shader.PropertyToID("_OutlineOffset1");
  155. ID_OutlineOffset2 = Shader.PropertyToID("_OutlineOffset2");
  156. ID_OutlineOffset3 = Shader.PropertyToID("_OutlineOffset3");
  157. ID_OutlineMode = Shader.PropertyToID("_OutlineMode");
  158. ID_IsoPerimeter = Shader.PropertyToID("_IsoPerimeter");
  159. ID_Softness = Shader.PropertyToID("_Softness");
  160. ID_UnderlayColor = Shader.PropertyToID("_UnderlayColor");
  161. ID_UnderlayOffsetX = Shader.PropertyToID("_UnderlayOffsetX");
  162. ID_UnderlayOffsetY = Shader.PropertyToID("_UnderlayOffsetY");
  163. ID_UnderlayDilate = Shader.PropertyToID("_UnderlayDilate");
  164. ID_UnderlaySoftness = Shader.PropertyToID("_UnderlaySoftness");
  165. ID_UnderlayOffset = Shader.PropertyToID("_UnderlayOffset");
  166. ID_UnderlayIsoPerimeter = Shader.PropertyToID("_UnderlayIsoPerimeter");
  167. ID_WeightNormal = Shader.PropertyToID("_WeightNormal");
  168. ID_WeightBold = Shader.PropertyToID("_WeightBold");
  169. ID_OutlineTex = Shader.PropertyToID("_OutlineTex");
  170. ID_OutlineWidth = Shader.PropertyToID("_OutlineWidth");
  171. ID_OutlineSoftness = Shader.PropertyToID("_OutlineSoftness");
  172. ID_OutlineColor = Shader.PropertyToID("_OutlineColor");
  173. ID_Outline2Color = Shader.PropertyToID("_Outline2Color");
  174. ID_Outline2Width = Shader.PropertyToID("_Outline2Width");
  175. ID_Padding = Shader.PropertyToID("_Padding");
  176. ID_GradientScale = Shader.PropertyToID("_GradientScale");
  177. ID_ScaleX = Shader.PropertyToID("_ScaleX");
  178. ID_ScaleY = Shader.PropertyToID("_ScaleY");
  179. ID_PerspectiveFilter = Shader.PropertyToID("_PerspectiveFilter");
  180. ID_Sharpness = Shader.PropertyToID("_Sharpness");
  181. ID_TextureWidth = Shader.PropertyToID("_TextureWidth");
  182. ID_TextureHeight = Shader.PropertyToID("_TextureHeight");
  183. ID_BevelAmount = Shader.PropertyToID("_Bevel");
  184. ID_LightAngle = Shader.PropertyToID("_LightAngle");
  185. ID_EnvMap = Shader.PropertyToID("_Cube");
  186. ID_EnvMatrix = Shader.PropertyToID("_EnvMatrix");
  187. ID_EnvMatrixRotation = Shader.PropertyToID("_EnvMatrixRotation");
  188. ID_GlowColor = Shader.PropertyToID("_GlowColor");
  189. ID_GlowOffset = Shader.PropertyToID("_GlowOffset");
  190. ID_GlowPower = Shader.PropertyToID("_GlowPower");
  191. ID_GlowOuter = Shader.PropertyToID("_GlowOuter");
  192. ID_GlowInner = Shader.PropertyToID("_GlowInner");
  193. //ID_MaskID = Shader.PropertyToID("_MaskID");
  194. ID_MaskCoord = Shader.PropertyToID("_MaskCoord");
  195. ID_ClipRect = Shader.PropertyToID("_ClipRect");
  196. ID_UseClipRect = Shader.PropertyToID("_UseClipRect");
  197. ID_MaskSoftnessX = Shader.PropertyToID("_MaskSoftnessX");
  198. ID_MaskSoftnessY = Shader.PropertyToID("_MaskSoftnessY");
  199. ID_VertexOffsetX = Shader.PropertyToID("_VertexOffsetX");
  200. ID_VertexOffsetY = Shader.PropertyToID("_VertexOffsetY");
  201. ID_StencilID = Shader.PropertyToID("_Stencil");
  202. ID_StencilOp = Shader.PropertyToID("_StencilOp");
  203. ID_StencilComp = Shader.PropertyToID("_StencilComp");
  204. ID_StencilReadMask = Shader.PropertyToID("_StencilReadMask");
  205. ID_StencilWriteMask = Shader.PropertyToID("_StencilWriteMask");
  206. ID_ShaderFlags = Shader.PropertyToID("_ShaderFlags");
  207. ID_ScaleRatio_A = Shader.PropertyToID("_ScaleRatioA");
  208. ID_ScaleRatio_B = Shader.PropertyToID("_ScaleRatioB");
  209. ID_ScaleRatio_C = Shader.PropertyToID("_ScaleRatioC");
  210. // Set internal shader references
  211. if (k_ShaderRef_MobileSDF == null)
  212. k_ShaderRef_MobileSDF = Shader.Find("TextMeshPro/Mobile/Distance Field");
  213. if (k_ShaderRef_MobileBitmap == null)
  214. k_ShaderRef_MobileBitmap = Shader.Find("TextMeshPro/Mobile/Bitmap");
  215. }
  216. }
  217. // Scale Ratios to ensure property ranges are optimum in Material Editor
  218. public static void UpdateShaderRatios(Material mat)
  219. {
  220. //Debug.Log("UpdateShaderRatios() called.");
  221. float ratio_A = 1;
  222. float ratio_B = 1;
  223. float ratio_C = 1;
  224. bool isRatioEnabled = !mat.shaderKeywords.Contains(Keyword_Ratios);
  225. if (!mat.HasProperty(ID_GradientScale) || !mat.HasProperty(ID_FaceDilate))
  226. return;
  227. // Compute Ratio A
  228. float scale = mat.GetFloat(ID_GradientScale);
  229. float faceDilate = mat.GetFloat(ID_FaceDilate);
  230. float outlineThickness = mat.GetFloat(ID_OutlineWidth);
  231. float outlineSoftness = mat.GetFloat(ID_OutlineSoftness);
  232. float weight = Mathf.Max(mat.GetFloat(ID_WeightNormal), mat.GetFloat(ID_WeightBold)) / 4.0f;
  233. float t = Mathf.Max(1, weight + faceDilate + outlineThickness + outlineSoftness);
  234. ratio_A = isRatioEnabled ? (scale - m_clamp) / (scale * t) : 1;
  235. //float ratio_A_old = mat.GetFloat(ID_ScaleRatio_A);
  236. // Only set the ratio if it has changed.
  237. //if (ratio_A != ratio_A_old)
  238. mat.SetFloat(ID_ScaleRatio_A, ratio_A);
  239. // Compute Ratio B
  240. if (mat.HasProperty(ID_GlowOffset))
  241. {
  242. float glowOffset = mat.GetFloat(ID_GlowOffset);
  243. float glowOuter = mat.GetFloat(ID_GlowOuter);
  244. float range = (weight + faceDilate) * (scale - m_clamp);
  245. t = Mathf.Max(1, glowOffset + glowOuter);
  246. ratio_B = isRatioEnabled ? Mathf.Max(0, scale - m_clamp - range) / (scale * t) : 1;
  247. //float ratio_B_old = mat.GetFloat(ID_ScaleRatio_B);
  248. // Only set the ratio if it has changed.
  249. //if (ratio_B != ratio_B_old)
  250. mat.SetFloat(ID_ScaleRatio_B, ratio_B);
  251. }
  252. // Compute Ratio C
  253. if (mat.HasProperty(ID_UnderlayOffsetX))
  254. {
  255. float underlayOffsetX = mat.GetFloat(ID_UnderlayOffsetX);
  256. float underlayOffsetY = mat.GetFloat(ID_UnderlayOffsetY);
  257. float underlayDilate = mat.GetFloat(ID_UnderlayDilate);
  258. float underlaySoftness = mat.GetFloat(ID_UnderlaySoftness);
  259. float range = (weight + faceDilate) * (scale - m_clamp);
  260. t = Mathf.Max(1, Mathf.Max(Mathf.Abs(underlayOffsetX), Mathf.Abs(underlayOffsetY)) + underlayDilate + underlaySoftness);
  261. ratio_C = isRatioEnabled ? Mathf.Max(0, scale - m_clamp - range) / (scale * t) : 1;
  262. //float ratio_C_old = mat.GetFloat(ID_ScaleRatio_C);
  263. // Only set the ratio if it has changed.
  264. //if (ratio_C != ratio_C_old)
  265. mat.SetFloat(ID_ScaleRatio_C, ratio_C);
  266. }
  267. }
  268. // Function to calculate padding required for Outline Width & Dilation for proper text alignment
  269. public static Vector4 GetFontExtent(Material material)
  270. {
  271. // Revised implementation where style no longer affects alignment
  272. return Vector4.zero;
  273. /*
  274. if (material == null || !material.HasProperty(ShaderUtilities.ID_GradientScale))
  275. return Vector4.zero; // We are using an non SDF Shader.
  276. float scaleRatioA = material.GetFloat(ID_ScaleRatio_A);
  277. float faceDilate = material.GetFloat(ID_FaceDilate) * scaleRatioA;
  278. float outlineThickness = material.GetFloat(ID_OutlineWidth) * scaleRatioA;
  279. float extent = Mathf.Min(1, faceDilate + outlineThickness);
  280. extent *= material.GetFloat(ID_GradientScale);
  281. return new Vector4(extent, extent, extent, extent);
  282. */
  283. }
  284. // Function to check if Masking is enabled
  285. public static bool IsMaskingEnabled(Material material)
  286. {
  287. if (material == null || !material.HasProperty(ShaderUtilities.ID_ClipRect))
  288. return false;
  289. if (material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_SOFT) || material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_HARD) || material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_TEX))
  290. return true;
  291. return false;
  292. }
  293. // Function to determine how much extra padding is required as a result of material properties like dilate, outline thickness, softness, glow, etc...
  294. public static float GetPadding(Material material, bool enableExtraPadding, bool isBold)
  295. {
  296. //Debug.Log("GetPadding() called.");
  297. if (isInitialized == false)
  298. GetShaderPropertyIDs();
  299. // Return if Material is null
  300. if (material == null) return 0;
  301. int extraPadding = enableExtraPadding ? 4 : 0;
  302. // Check if we are using a non Distance Field Shader
  303. if (material.HasProperty(ID_GradientScale) == false)
  304. {
  305. if (material.HasProperty(ID_Padding))
  306. extraPadding += (int)material.GetFloat(ID_Padding);
  307. return extraPadding + 1.0f;
  308. }
  309. // Special handling for new SRP Shaders
  310. if (material.HasProperty(ID_IsoPerimeter))
  311. {
  312. return ComputePaddingForProperties(material) + 0.25f + extraPadding;
  313. }
  314. Vector4 padding = Vector4.zero;
  315. Vector4 maxPadding = Vector4.zero;
  316. //float weight = 0;
  317. float faceDilate = 0;
  318. float faceSoftness = 0;
  319. float outlineThickness = 0;
  320. float scaleRatio_A = 0;
  321. float scaleRatio_B = 0;
  322. float scaleRatio_C = 0;
  323. float glowOffset = 0;
  324. float glowOuter = 0;
  325. float gradientScale = 0;
  326. float uniformPadding = 0;
  327. // Iterate through each of the assigned materials to find the max values to set the padding.
  328. // Update Shader Ratios prior to computing padding
  329. UpdateShaderRatios(material);
  330. string[] shaderKeywords = material.shaderKeywords;
  331. if (material.HasProperty(ID_ScaleRatio_A))
  332. scaleRatio_A = material.GetFloat(ID_ScaleRatio_A);
  333. //weight = 0; // Mathf.Max(material.GetFloat(ID_WeightNormal), material.GetFloat(ID_WeightBold)) / 2.0f * scaleRatio_A;
  334. if (material.HasProperty(ID_FaceDilate))
  335. faceDilate = material.GetFloat(ID_FaceDilate) * scaleRatio_A;
  336. if (material.HasProperty(ID_OutlineSoftness))
  337. faceSoftness = material.GetFloat(ID_OutlineSoftness) * scaleRatio_A;
  338. if (material.HasProperty(ID_OutlineWidth))
  339. outlineThickness = material.GetFloat(ID_OutlineWidth) * scaleRatio_A;
  340. uniformPadding = outlineThickness + faceSoftness + faceDilate;
  341. // Glow padding contribution
  342. if (material.HasProperty(ID_GlowOffset) && shaderKeywords.Contains(Keyword_Glow)) // Generates GC
  343. {
  344. if (material.HasProperty(ID_ScaleRatio_B))
  345. scaleRatio_B = material.GetFloat(ID_ScaleRatio_B);
  346. glowOffset = material.GetFloat(ID_GlowOffset) * scaleRatio_B;
  347. glowOuter = material.GetFloat(ID_GlowOuter) * scaleRatio_B;
  348. }
  349. uniformPadding = Mathf.Max(uniformPadding, faceDilate + glowOffset + glowOuter);
  350. // Underlay padding contribution
  351. if (material.HasProperty(ID_UnderlaySoftness) && shaderKeywords.Contains(Keyword_Underlay)) // Generates GC
  352. {
  353. if (material.HasProperty(ID_ScaleRatio_C))
  354. scaleRatio_C = material.GetFloat(ID_ScaleRatio_C);
  355. float offsetX = 0;
  356. float offsetY = 0;
  357. float dilate = 0;
  358. float softness = 0;
  359. if (material.HasProperty(ID_UnderlayOffset))
  360. {
  361. Vector2 underlayOffset = material.GetVector(ID_UnderlayOffset);
  362. offsetX = underlayOffset.x;
  363. offsetY = underlayOffset.y;
  364. dilate = material.GetFloat(ID_UnderlayDilate);
  365. softness = material.GetFloat(ID_UnderlaySoftness);
  366. }
  367. else if (material.HasProperty(ID_UnderlayOffsetX))
  368. {
  369. offsetX = material.GetFloat(ID_UnderlayOffsetX) * scaleRatio_C;
  370. offsetY = material.GetFloat(ID_UnderlayOffsetY) * scaleRatio_C;
  371. dilate = material.GetFloat(ID_UnderlayDilate) * scaleRatio_C;
  372. softness = material.GetFloat(ID_UnderlaySoftness) * scaleRatio_C;
  373. }
  374. padding.x = Mathf.Max(padding.x, faceDilate + dilate + softness - offsetX);
  375. padding.y = Mathf.Max(padding.y, faceDilate + dilate + softness - offsetY);
  376. padding.z = Mathf.Max(padding.z, faceDilate + dilate + softness + offsetX);
  377. padding.w = Mathf.Max(padding.w, faceDilate + dilate + softness + offsetY);
  378. }
  379. padding.x = Mathf.Max(padding.x, uniformPadding);
  380. padding.y = Mathf.Max(padding.y, uniformPadding);
  381. padding.z = Mathf.Max(padding.z, uniformPadding);
  382. padding.w = Mathf.Max(padding.w, uniformPadding);
  383. padding.x += extraPadding;
  384. padding.y += extraPadding;
  385. padding.z += extraPadding;
  386. padding.w += extraPadding;
  387. padding.x = Mathf.Min(padding.x, 1);
  388. padding.y = Mathf.Min(padding.y, 1);
  389. padding.z = Mathf.Min(padding.z, 1);
  390. padding.w = Mathf.Min(padding.w, 1);
  391. maxPadding.x = maxPadding.x < padding.x ? padding.x : maxPadding.x;
  392. maxPadding.y = maxPadding.y < padding.y ? padding.y : maxPadding.y;
  393. maxPadding.z = maxPadding.z < padding.z ? padding.z : maxPadding.z;
  394. maxPadding.w = maxPadding.w < padding.w ? padding.w : maxPadding.w;
  395. gradientScale = material.GetFloat(ID_GradientScale);
  396. padding *= gradientScale;
  397. // Set UniformPadding to the maximum value of any of its components.
  398. uniformPadding = Mathf.Max(padding.x, padding.y);
  399. uniformPadding = Mathf.Max(padding.z, uniformPadding);
  400. uniformPadding = Mathf.Max(padding.w, uniformPadding);
  401. return uniformPadding + 1.25f;
  402. }
  403. static float ComputePaddingForProperties(Material mat)
  404. {
  405. Vector4 dilation = mat.GetVector(ID_IsoPerimeter);
  406. Vector2 outlineOffset1 = mat.GetVector(ID_OutlineOffset1);
  407. Vector2 outlineOffset2 = mat.GetVector(ID_OutlineOffset2);
  408. Vector2 outlineOffset3 = mat.GetVector(ID_OutlineOffset3);
  409. bool isOutlineModeEnabled = mat.GetFloat(ID_OutlineMode) != 0;
  410. Vector4 softness = mat.GetVector(ID_Softness);
  411. float gradientScale = mat.GetFloat(ID_GradientScale);
  412. // Face
  413. float padding = Mathf.Max(0, dilation.x + softness.x * 0.5f);
  414. // Outlines
  415. if (!isOutlineModeEnabled)
  416. {
  417. padding = Mathf.Max(padding, dilation.y + softness.y * 0.5f + Mathf.Max(Mathf.Abs(outlineOffset1.x), Mathf.Abs(outlineOffset1.y)));
  418. padding = Mathf.Max(padding, dilation.z + softness.z * 0.5f + Mathf.Max(Mathf.Abs(outlineOffset2.x), Mathf.Abs(outlineOffset2.y)));
  419. padding = Mathf.Max(padding, dilation.w + softness.w * 0.5f + Mathf.Max(Mathf.Abs(outlineOffset3.x), Mathf.Abs(outlineOffset3.y)));
  420. }
  421. else
  422. {
  423. float offsetOutline1 = Mathf.Max(Mathf.Abs(outlineOffset1.x), Mathf.Abs(outlineOffset1.y));
  424. float offsetOutline2 = Mathf.Max(Mathf.Abs(outlineOffset2.x), Mathf.Abs(outlineOffset2.y));
  425. padding = Mathf.Max(padding, dilation.y + softness.y * 0.5f + offsetOutline1);
  426. padding = Mathf.Max(padding, dilation.z + softness.z * 0.5f + offsetOutline2);
  427. float maxOffset = Mathf.Max(offsetOutline1, offsetOutline2);
  428. padding += Mathf.Max(0 ,(dilation.w + softness.w * 0.5f) - Mathf.Max(0, padding - maxOffset));
  429. }
  430. // Underlay
  431. Vector2 underlayOffset = mat.GetVector(ID_UnderlayOffset);
  432. float underlayDilation = mat.GetFloat(ID_UnderlayDilate);
  433. float underlaySoftness = mat.GetFloat(ID_UnderlaySoftness);
  434. padding = Mathf.Max(padding, underlayDilation + underlaySoftness * 0.5f + Mathf.Max(Mathf.Abs(underlayOffset.x), Mathf.Abs(underlayOffset.y)));
  435. return padding * gradientScale;
  436. }
  437. // Function to determine how much extra padding is required as a result of material properties like dilate, outline thickness, softness, glow, etc...
  438. public static float GetPadding(Material[] materials, bool enableExtraPadding, bool isBold)
  439. {
  440. //Debug.Log("GetPadding() called.");
  441. if (isInitialized == false)
  442. GetShaderPropertyIDs();
  443. // Return if Material is null
  444. if (materials == null) return 0;
  445. int extraPadding = enableExtraPadding ? 4 : 0;
  446. // Check if we are using a Bitmap Shader
  447. if (materials[0].HasProperty(ID_Padding))
  448. return extraPadding + materials[0].GetFloat(ID_Padding);
  449. Vector4 padding = Vector4.zero;
  450. Vector4 maxPadding = Vector4.zero;
  451. float faceDilate = 0;
  452. float faceSoftness = 0;
  453. float outlineThickness = 0;
  454. float scaleRatio_A = 0;
  455. float scaleRatio_B = 0;
  456. float scaleRatio_C = 0;
  457. float glowOffset = 0;
  458. float glowOuter = 0;
  459. float uniformPadding = 0;
  460. // Iterate through each of the assigned materials to find the max values to set the padding.
  461. for (int i = 0; i < materials.Length; i++)
  462. {
  463. // Update Shader Ratios prior to computing padding
  464. ShaderUtilities.UpdateShaderRatios(materials[i]);
  465. string[] shaderKeywords = materials[i].shaderKeywords;
  466. if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_A))
  467. scaleRatio_A = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_A);
  468. if (materials[i].HasProperty(ShaderUtilities.ID_FaceDilate))
  469. faceDilate = materials[i].GetFloat(ShaderUtilities.ID_FaceDilate) * scaleRatio_A;
  470. if (materials[i].HasProperty(ShaderUtilities.ID_OutlineSoftness))
  471. faceSoftness = materials[i].GetFloat(ShaderUtilities.ID_OutlineSoftness) * scaleRatio_A;
  472. if (materials[i].HasProperty(ShaderUtilities.ID_OutlineWidth))
  473. outlineThickness = materials[i].GetFloat(ShaderUtilities.ID_OutlineWidth) * scaleRatio_A;
  474. uniformPadding = outlineThickness + faceSoftness + faceDilate;
  475. // Glow padding contribution
  476. if (materials[i].HasProperty(ShaderUtilities.ID_GlowOffset) && shaderKeywords.Contains(ShaderUtilities.Keyword_Glow))
  477. {
  478. if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_B))
  479. scaleRatio_B = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_B);
  480. glowOffset = materials[i].GetFloat(ShaderUtilities.ID_GlowOffset) * scaleRatio_B;
  481. glowOuter = materials[i].GetFloat(ShaderUtilities.ID_GlowOuter) * scaleRatio_B;
  482. }
  483. uniformPadding = Mathf.Max(uniformPadding, faceDilate + glowOffset + glowOuter);
  484. // Underlay padding contribution
  485. if (materials[i].HasProperty(ShaderUtilities.ID_UnderlaySoftness) && shaderKeywords.Contains(ShaderUtilities.Keyword_Underlay))
  486. {
  487. if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_C))
  488. scaleRatio_C = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_C);
  489. float offsetX = materials[i].GetFloat(ShaderUtilities.ID_UnderlayOffsetX) * scaleRatio_C;
  490. float offsetY = materials[i].GetFloat(ShaderUtilities.ID_UnderlayOffsetY) * scaleRatio_C;
  491. float dilate = materials[i].GetFloat(ShaderUtilities.ID_UnderlayDilate) * scaleRatio_C;
  492. float softness = materials[i].GetFloat(ShaderUtilities.ID_UnderlaySoftness) * scaleRatio_C;
  493. padding.x = Mathf.Max(padding.x, faceDilate + dilate + softness - offsetX);
  494. padding.y = Mathf.Max(padding.y, faceDilate + dilate + softness - offsetY);
  495. padding.z = Mathf.Max(padding.z, faceDilate + dilate + softness + offsetX);
  496. padding.w = Mathf.Max(padding.w, faceDilate + dilate + softness + offsetY);
  497. }
  498. padding.x = Mathf.Max(padding.x, uniformPadding);
  499. padding.y = Mathf.Max(padding.y, uniformPadding);
  500. padding.z = Mathf.Max(padding.z, uniformPadding);
  501. padding.w = Mathf.Max(padding.w, uniformPadding);
  502. padding.x += extraPadding;
  503. padding.y += extraPadding;
  504. padding.z += extraPadding;
  505. padding.w += extraPadding;
  506. padding.x = Mathf.Min(padding.x, 1);
  507. padding.y = Mathf.Min(padding.y, 1);
  508. padding.z = Mathf.Min(padding.z, 1);
  509. padding.w = Mathf.Min(padding.w, 1);
  510. maxPadding.x = maxPadding.x < padding.x ? padding.x : maxPadding.x;
  511. maxPadding.y = maxPadding.y < padding.y ? padding.y : maxPadding.y;
  512. maxPadding.z = maxPadding.z < padding.z ? padding.z : maxPadding.z;
  513. maxPadding.w = maxPadding.w < padding.w ? padding.w : maxPadding.w;
  514. }
  515. float gradientScale = materials[0].GetFloat(ShaderUtilities.ID_GradientScale);
  516. padding *= gradientScale;
  517. // Set UniformPadding to the maximum value of any of its components.
  518. uniformPadding = Mathf.Max(padding.x, padding.y);
  519. uniformPadding = Mathf.Max(padding.z, uniformPadding);
  520. uniformPadding = Mathf.Max(padding.w, uniformPadding);
  521. return uniformPadding + 0.25f;
  522. }
  523. }
  524. }