691 lines
29 KiB
C#
691 lines
29 KiB
C#
|
using UnityEngine;
|
|||
|
using System.Linq;
|
|||
|
using System.Collections;
|
|||
|
|
|||
|
|
|||
|
namespace TMPro
|
|||
|
{
|
|||
|
public static class ShaderUtilities
|
|||
|
{
|
|||
|
// Shader Property IDs
|
|||
|
public static int ID_MainTex;
|
|||
|
|
|||
|
public static int ID_FaceTex;
|
|||
|
public static int ID_FaceColor;
|
|||
|
public static int ID_FaceDilate;
|
|||
|
public static int ID_Shininess;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Property ID for the _OutlineOffset1 shader property used by URP and HDRP shaders
|
|||
|
/// </summary>
|
|||
|
public static int ID_OutlineOffset1;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Property ID for the _OutlineOffset2 shader property used by URP and HDRP shaders
|
|||
|
/// </summary>
|
|||
|
public static int ID_OutlineOffset2;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Property ID for the _OutlineOffset3 shader property used by URP and HDRP shaders
|
|||
|
/// </summary>
|
|||
|
public static int ID_OutlineOffset3;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Property ID for the ID_AdditiveOutlineMode shader property used by URP and HDRP shaders
|
|||
|
/// </summary>
|
|||
|
public static int ID_OutlineMode;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Property ID for the _IsoPerimeter shader property used by URP and HDRP shaders
|
|||
|
/// </summary>
|
|||
|
public static int ID_IsoPerimeter;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Property ID for the _Softness shader property used by URP and HDRP shaders
|
|||
|
/// </summary>
|
|||
|
public static int ID_Softness;
|
|||
|
|
|||
|
public static int ID_UnderlayColor;
|
|||
|
public static int ID_UnderlayOffsetX;
|
|||
|
public static int ID_UnderlayOffsetY;
|
|||
|
public static int ID_UnderlayDilate;
|
|||
|
public static int ID_UnderlaySoftness;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Property ID for the _UnderlayOffset shader property used by URP and HDRP shaders
|
|||
|
/// </summary>
|
|||
|
public static int ID_UnderlayOffset;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Property ID for the _UnderlayIsoPerimeter shader property used by URP and HDRP shaders
|
|||
|
/// </summary>
|
|||
|
public static int ID_UnderlayIsoPerimeter;
|
|||
|
|
|||
|
public static int ID_WeightNormal;
|
|||
|
public static int ID_WeightBold;
|
|||
|
|
|||
|
public static int ID_OutlineTex;
|
|||
|
public static int ID_OutlineWidth;
|
|||
|
public static int ID_OutlineSoftness;
|
|||
|
public static int ID_OutlineColor;
|
|||
|
|
|||
|
public static int ID_Outline2Color;
|
|||
|
public static int ID_Outline2Width;
|
|||
|
|
|||
|
public static int ID_Padding;
|
|||
|
public static int ID_GradientScale;
|
|||
|
public static int ID_ScaleX;
|
|||
|
public static int ID_ScaleY;
|
|||
|
public static int ID_PerspectiveFilter;
|
|||
|
public static int ID_Sharpness;
|
|||
|
|
|||
|
public static int ID_TextureWidth;
|
|||
|
public static int ID_TextureHeight;
|
|||
|
|
|||
|
public static int ID_BevelAmount;
|
|||
|
|
|||
|
public static int ID_GlowColor;
|
|||
|
public static int ID_GlowOffset;
|
|||
|
public static int ID_GlowPower;
|
|||
|
public static int ID_GlowOuter;
|
|||
|
public static int ID_GlowInner;
|
|||
|
|
|||
|
public static int ID_LightAngle;
|
|||
|
|
|||
|
public static int ID_EnvMap;
|
|||
|
public static int ID_EnvMatrix;
|
|||
|
public static int ID_EnvMatrixRotation;
|
|||
|
|
|||
|
//public static int ID_MaskID;
|
|||
|
public static int ID_MaskCoord;
|
|||
|
public static int ID_ClipRect;
|
|||
|
public static int ID_MaskSoftnessX;
|
|||
|
public static int ID_MaskSoftnessY;
|
|||
|
public static int ID_VertexOffsetX;
|
|||
|
public static int ID_VertexOffsetY;
|
|||
|
public static int ID_UseClipRect;
|
|||
|
|
|||
|
public static int ID_StencilID;
|
|||
|
public static int ID_StencilOp;
|
|||
|
public static int ID_StencilComp;
|
|||
|
public static int ID_StencilReadMask;
|
|||
|
public static int ID_StencilWriteMask;
|
|||
|
|
|||
|
public static int ID_ShaderFlags;
|
|||
|
public static int ID_ScaleRatio_A;
|
|||
|
public static int ID_ScaleRatio_B;
|
|||
|
public static int ID_ScaleRatio_C;
|
|||
|
|
|||
|
public static string Keyword_Bevel = "BEVEL_ON";
|
|||
|
public static string Keyword_Glow = "GLOW_ON";
|
|||
|
public static string Keyword_Underlay = "UNDERLAY_ON";
|
|||
|
public static string Keyword_Ratios = "RATIOS_OFF";
|
|||
|
//public static string Keyword_MASK_OFF = "MASK_OFF";
|
|||
|
public static string Keyword_MASK_SOFT = "MASK_SOFT";
|
|||
|
public static string Keyword_MASK_HARD = "MASK_HARD";
|
|||
|
public static string Keyword_MASK_TEX = "MASK_TEX";
|
|||
|
public static string Keyword_Outline = "OUTLINE_ON";
|
|||
|
|
|||
|
public static string ShaderTag_ZTestMode = "unity_GUIZTestMode";
|
|||
|
public static string ShaderTag_CullMode = "_CullMode";
|
|||
|
|
|||
|
private static float m_clamp = 1.0f;
|
|||
|
public static bool isInitialized = false;
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns a reference to the mobile distance field shader.
|
|||
|
/// </summary>
|
|||
|
internal static Shader ShaderRef_MobileSDF
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
if (k_ShaderRef_MobileSDF == null)
|
|||
|
k_ShaderRef_MobileSDF = Shader.Find("TextMeshPro/Mobile/Distance Field");
|
|||
|
|
|||
|
return k_ShaderRef_MobileSDF;
|
|||
|
}
|
|||
|
}
|
|||
|
static Shader k_ShaderRef_MobileSDF;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns a reference to the mobile bitmap shader.
|
|||
|
/// </summary>
|
|||
|
internal static Shader ShaderRef_MobileBitmap
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
if (k_ShaderRef_MobileBitmap == null)
|
|||
|
k_ShaderRef_MobileBitmap = Shader.Find("TextMeshPro/Mobile/Bitmap");
|
|||
|
|
|||
|
return k_ShaderRef_MobileBitmap;
|
|||
|
}
|
|||
|
}
|
|||
|
static Shader k_ShaderRef_MobileBitmap;
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
static ShaderUtilities()
|
|||
|
{
|
|||
|
GetShaderPropertyIDs();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public static void GetShaderPropertyIDs()
|
|||
|
{
|
|||
|
if (isInitialized == false)
|
|||
|
{
|
|||
|
//Debug.Log("Getting Shader property IDs");
|
|||
|
isInitialized = true;
|
|||
|
|
|||
|
ID_MainTex = Shader.PropertyToID("_MainTex");
|
|||
|
|
|||
|
ID_FaceTex = Shader.PropertyToID("_FaceTex");
|
|||
|
ID_FaceColor = Shader.PropertyToID("_FaceColor");
|
|||
|
ID_FaceDilate = Shader.PropertyToID("_FaceDilate");
|
|||
|
ID_Shininess = Shader.PropertyToID("_FaceShininess");
|
|||
|
|
|||
|
ID_OutlineOffset1 = Shader.PropertyToID("_OutlineOffset1");
|
|||
|
ID_OutlineOffset2 = Shader.PropertyToID("_OutlineOffset2");
|
|||
|
ID_OutlineOffset3 = Shader.PropertyToID("_OutlineOffset3");
|
|||
|
ID_OutlineMode = Shader.PropertyToID("_OutlineMode");
|
|||
|
|
|||
|
ID_IsoPerimeter = Shader.PropertyToID("_IsoPerimeter");
|
|||
|
ID_Softness = Shader.PropertyToID("_Softness");
|
|||
|
|
|||
|
ID_UnderlayColor = Shader.PropertyToID("_UnderlayColor");
|
|||
|
ID_UnderlayOffsetX = Shader.PropertyToID("_UnderlayOffsetX");
|
|||
|
ID_UnderlayOffsetY = Shader.PropertyToID("_UnderlayOffsetY");
|
|||
|
ID_UnderlayDilate = Shader.PropertyToID("_UnderlayDilate");
|
|||
|
ID_UnderlaySoftness = Shader.PropertyToID("_UnderlaySoftness");
|
|||
|
|
|||
|
ID_UnderlayOffset = Shader.PropertyToID("_UnderlayOffset");
|
|||
|
ID_UnderlayIsoPerimeter = Shader.PropertyToID("_UnderlayIsoPerimeter");
|
|||
|
|
|||
|
ID_WeightNormal = Shader.PropertyToID("_WeightNormal");
|
|||
|
ID_WeightBold = Shader.PropertyToID("_WeightBold");
|
|||
|
|
|||
|
ID_OutlineTex = Shader.PropertyToID("_OutlineTex");
|
|||
|
ID_OutlineWidth = Shader.PropertyToID("_OutlineWidth");
|
|||
|
ID_OutlineSoftness = Shader.PropertyToID("_OutlineSoftness");
|
|||
|
ID_OutlineColor = Shader.PropertyToID("_OutlineColor");
|
|||
|
|
|||
|
ID_Outline2Color = Shader.PropertyToID("_Outline2Color");
|
|||
|
ID_Outline2Width = Shader.PropertyToID("_Outline2Width");
|
|||
|
|
|||
|
ID_Padding = Shader.PropertyToID("_Padding");
|
|||
|
ID_GradientScale = Shader.PropertyToID("_GradientScale");
|
|||
|
ID_ScaleX = Shader.PropertyToID("_ScaleX");
|
|||
|
ID_ScaleY = Shader.PropertyToID("_ScaleY");
|
|||
|
ID_PerspectiveFilter = Shader.PropertyToID("_PerspectiveFilter");
|
|||
|
ID_Sharpness = Shader.PropertyToID("_Sharpness");
|
|||
|
|
|||
|
ID_TextureWidth = Shader.PropertyToID("_TextureWidth");
|
|||
|
ID_TextureHeight = Shader.PropertyToID("_TextureHeight");
|
|||
|
|
|||
|
ID_BevelAmount = Shader.PropertyToID("_Bevel");
|
|||
|
|
|||
|
ID_LightAngle = Shader.PropertyToID("_LightAngle");
|
|||
|
|
|||
|
ID_EnvMap = Shader.PropertyToID("_Cube");
|
|||
|
ID_EnvMatrix = Shader.PropertyToID("_EnvMatrix");
|
|||
|
ID_EnvMatrixRotation = Shader.PropertyToID("_EnvMatrixRotation");
|
|||
|
|
|||
|
|
|||
|
ID_GlowColor = Shader.PropertyToID("_GlowColor");
|
|||
|
ID_GlowOffset = Shader.PropertyToID("_GlowOffset");
|
|||
|
ID_GlowPower = Shader.PropertyToID("_GlowPower");
|
|||
|
ID_GlowOuter = Shader.PropertyToID("_GlowOuter");
|
|||
|
ID_GlowInner = Shader.PropertyToID("_GlowInner");
|
|||
|
|
|||
|
//ID_MaskID = Shader.PropertyToID("_MaskID");
|
|||
|
ID_MaskCoord = Shader.PropertyToID("_MaskCoord");
|
|||
|
ID_ClipRect = Shader.PropertyToID("_ClipRect");
|
|||
|
ID_UseClipRect = Shader.PropertyToID("_UseClipRect");
|
|||
|
ID_MaskSoftnessX = Shader.PropertyToID("_MaskSoftnessX");
|
|||
|
ID_MaskSoftnessY = Shader.PropertyToID("_MaskSoftnessY");
|
|||
|
ID_VertexOffsetX = Shader.PropertyToID("_VertexOffsetX");
|
|||
|
ID_VertexOffsetY = Shader.PropertyToID("_VertexOffsetY");
|
|||
|
|
|||
|
ID_StencilID = Shader.PropertyToID("_Stencil");
|
|||
|
ID_StencilOp = Shader.PropertyToID("_StencilOp");
|
|||
|
ID_StencilComp = Shader.PropertyToID("_StencilComp");
|
|||
|
ID_StencilReadMask = Shader.PropertyToID("_StencilReadMask");
|
|||
|
ID_StencilWriteMask = Shader.PropertyToID("_StencilWriteMask");
|
|||
|
|
|||
|
ID_ShaderFlags = Shader.PropertyToID("_ShaderFlags");
|
|||
|
ID_ScaleRatio_A = Shader.PropertyToID("_ScaleRatioA");
|
|||
|
ID_ScaleRatio_B = Shader.PropertyToID("_ScaleRatioB");
|
|||
|
ID_ScaleRatio_C = Shader.PropertyToID("_ScaleRatioC");
|
|||
|
|
|||
|
// Set internal shader references
|
|||
|
if (k_ShaderRef_MobileSDF == null)
|
|||
|
k_ShaderRef_MobileSDF = Shader.Find("TextMeshPro/Mobile/Distance Field");
|
|||
|
|
|||
|
if (k_ShaderRef_MobileBitmap == null)
|
|||
|
k_ShaderRef_MobileBitmap = Shader.Find("TextMeshPro/Mobile/Bitmap");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// Scale Ratios to ensure property ranges are optimum in Material Editor
|
|||
|
public static void UpdateShaderRatios(Material mat)
|
|||
|
{
|
|||
|
//Debug.Log("UpdateShaderRatios() called.");
|
|||
|
|
|||
|
float ratio_A = 1;
|
|||
|
float ratio_B = 1;
|
|||
|
float ratio_C = 1;
|
|||
|
|
|||
|
bool isRatioEnabled = !mat.shaderKeywords.Contains(Keyword_Ratios);
|
|||
|
|
|||
|
if (!mat.HasProperty(ID_GradientScale) || !mat.HasProperty(ID_FaceDilate))
|
|||
|
return;
|
|||
|
|
|||
|
// Compute Ratio A
|
|||
|
float scale = mat.GetFloat(ID_GradientScale);
|
|||
|
float faceDilate = mat.GetFloat(ID_FaceDilate);
|
|||
|
float outlineThickness = mat.GetFloat(ID_OutlineWidth);
|
|||
|
float outlineSoftness = mat.GetFloat(ID_OutlineSoftness);
|
|||
|
|
|||
|
float weight = Mathf.Max(mat.GetFloat(ID_WeightNormal), mat.GetFloat(ID_WeightBold)) / 4.0f;
|
|||
|
|
|||
|
float t = Mathf.Max(1, weight + faceDilate + outlineThickness + outlineSoftness);
|
|||
|
|
|||
|
ratio_A = isRatioEnabled ? (scale - m_clamp) / (scale * t) : 1;
|
|||
|
|
|||
|
//float ratio_A_old = mat.GetFloat(ID_ScaleRatio_A);
|
|||
|
|
|||
|
// Only set the ratio if it has changed.
|
|||
|
//if (ratio_A != ratio_A_old)
|
|||
|
mat.SetFloat(ID_ScaleRatio_A, ratio_A);
|
|||
|
|
|||
|
// Compute Ratio B
|
|||
|
if (mat.HasProperty(ID_GlowOffset))
|
|||
|
{
|
|||
|
float glowOffset = mat.GetFloat(ID_GlowOffset);
|
|||
|
float glowOuter = mat.GetFloat(ID_GlowOuter);
|
|||
|
|
|||
|
float range = (weight + faceDilate) * (scale - m_clamp);
|
|||
|
|
|||
|
t = Mathf.Max(1, glowOffset + glowOuter);
|
|||
|
|
|||
|
ratio_B = isRatioEnabled ? Mathf.Max(0, scale - m_clamp - range) / (scale * t) : 1;
|
|||
|
//float ratio_B_old = mat.GetFloat(ID_ScaleRatio_B);
|
|||
|
|
|||
|
// Only set the ratio if it has changed.
|
|||
|
//if (ratio_B != ratio_B_old)
|
|||
|
mat.SetFloat(ID_ScaleRatio_B, ratio_B);
|
|||
|
}
|
|||
|
|
|||
|
// Compute Ratio C
|
|||
|
if (mat.HasProperty(ID_UnderlayOffsetX))
|
|||
|
{
|
|||
|
float underlayOffsetX = mat.GetFloat(ID_UnderlayOffsetX);
|
|||
|
float underlayOffsetY = mat.GetFloat(ID_UnderlayOffsetY);
|
|||
|
float underlayDilate = mat.GetFloat(ID_UnderlayDilate);
|
|||
|
float underlaySoftness = mat.GetFloat(ID_UnderlaySoftness);
|
|||
|
|
|||
|
float range = (weight + faceDilate) * (scale - m_clamp);
|
|||
|
|
|||
|
t = Mathf.Max(1, Mathf.Max(Mathf.Abs(underlayOffsetX), Mathf.Abs(underlayOffsetY)) + underlayDilate + underlaySoftness);
|
|||
|
|
|||
|
ratio_C = isRatioEnabled ? Mathf.Max(0, scale - m_clamp - range) / (scale * t) : 1;
|
|||
|
//float ratio_C_old = mat.GetFloat(ID_ScaleRatio_C);
|
|||
|
|
|||
|
// Only set the ratio if it has changed.
|
|||
|
//if (ratio_C != ratio_C_old)
|
|||
|
mat.SetFloat(ID_ScaleRatio_C, ratio_C);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// Function to calculate padding required for Outline Width & Dilation for proper text alignment
|
|||
|
public static Vector4 GetFontExtent(Material material)
|
|||
|
{
|
|||
|
// Revised implementation where style no longer affects alignment
|
|||
|
return Vector4.zero;
|
|||
|
|
|||
|
/*
|
|||
|
if (material == null || !material.HasProperty(ShaderUtilities.ID_GradientScale))
|
|||
|
return Vector4.zero; // We are using an non SDF Shader.
|
|||
|
|
|||
|
float scaleRatioA = material.GetFloat(ID_ScaleRatio_A);
|
|||
|
float faceDilate = material.GetFloat(ID_FaceDilate) * scaleRatioA;
|
|||
|
float outlineThickness = material.GetFloat(ID_OutlineWidth) * scaleRatioA;
|
|||
|
|
|||
|
float extent = Mathf.Min(1, faceDilate + outlineThickness);
|
|||
|
extent *= material.GetFloat(ID_GradientScale);
|
|||
|
|
|||
|
return new Vector4(extent, extent, extent, extent);
|
|||
|
*/
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Function to check if Masking is enabled
|
|||
|
public static bool IsMaskingEnabled(Material material)
|
|||
|
{
|
|||
|
if (material == null || !material.HasProperty(ShaderUtilities.ID_ClipRect))
|
|||
|
return false;
|
|||
|
|
|||
|
if (material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_SOFT) || material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_HARD) || material.shaderKeywords.Contains(ShaderUtilities.Keyword_MASK_TEX))
|
|||
|
return true;
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Function to determine how much extra padding is required as a result of material properties like dilate, outline thickness, softness, glow, etc...
|
|||
|
public static float GetPadding(Material material, bool enableExtraPadding, bool isBold)
|
|||
|
{
|
|||
|
//Debug.Log("GetPadding() called.");
|
|||
|
|
|||
|
if (isInitialized == false)
|
|||
|
GetShaderPropertyIDs();
|
|||
|
|
|||
|
// Return if Material is null
|
|||
|
if (material == null) return 0;
|
|||
|
|
|||
|
int extraPadding = enableExtraPadding ? 4 : 0;
|
|||
|
|
|||
|
// Check if we are using a non Distance Field Shader
|
|||
|
if (material.HasProperty(ID_GradientScale) == false)
|
|||
|
{
|
|||
|
if (material.HasProperty(ID_Padding))
|
|||
|
extraPadding += (int)material.GetFloat(ID_Padding);
|
|||
|
|
|||
|
return extraPadding + 1.0f;
|
|||
|
}
|
|||
|
|
|||
|
// Special handling for new SRP Shaders
|
|||
|
if (material.HasProperty(ID_IsoPerimeter))
|
|||
|
{
|
|||
|
return ComputePaddingForProperties(material) + 0.25f + extraPadding;
|
|||
|
}
|
|||
|
|
|||
|
Vector4 padding = Vector4.zero;
|
|||
|
Vector4 maxPadding = Vector4.zero;
|
|||
|
|
|||
|
//float weight = 0;
|
|||
|
float faceDilate = 0;
|
|||
|
float faceSoftness = 0;
|
|||
|
float outlineThickness = 0;
|
|||
|
float scaleRatio_A = 0;
|
|||
|
float scaleRatio_B = 0;
|
|||
|
float scaleRatio_C = 0;
|
|||
|
|
|||
|
float glowOffset = 0;
|
|||
|
float glowOuter = 0;
|
|||
|
|
|||
|
float gradientScale = 0;
|
|||
|
float uniformPadding = 0;
|
|||
|
// Iterate through each of the assigned materials to find the max values to set the padding.
|
|||
|
|
|||
|
// Update Shader Ratios prior to computing padding
|
|||
|
UpdateShaderRatios(material);
|
|||
|
|
|||
|
string[] shaderKeywords = material.shaderKeywords;
|
|||
|
|
|||
|
if (material.HasProperty(ID_ScaleRatio_A))
|
|||
|
scaleRatio_A = material.GetFloat(ID_ScaleRatio_A);
|
|||
|
|
|||
|
//weight = 0; // Mathf.Max(material.GetFloat(ID_WeightNormal), material.GetFloat(ID_WeightBold)) / 2.0f * scaleRatio_A;
|
|||
|
|
|||
|
if (material.HasProperty(ID_FaceDilate))
|
|||
|
faceDilate = material.GetFloat(ID_FaceDilate) * scaleRatio_A;
|
|||
|
|
|||
|
if (material.HasProperty(ID_OutlineSoftness))
|
|||
|
faceSoftness = material.GetFloat(ID_OutlineSoftness) * scaleRatio_A;
|
|||
|
|
|||
|
if (material.HasProperty(ID_OutlineWidth))
|
|||
|
outlineThickness = material.GetFloat(ID_OutlineWidth) * scaleRatio_A;
|
|||
|
|
|||
|
uniformPadding = outlineThickness + faceSoftness + faceDilate;
|
|||
|
|
|||
|
// Glow padding contribution
|
|||
|
if (material.HasProperty(ID_GlowOffset) && shaderKeywords.Contains(Keyword_Glow)) // Generates GC
|
|||
|
{
|
|||
|
if (material.HasProperty(ID_ScaleRatio_B))
|
|||
|
scaleRatio_B = material.GetFloat(ID_ScaleRatio_B);
|
|||
|
|
|||
|
glowOffset = material.GetFloat(ID_GlowOffset) * scaleRatio_B;
|
|||
|
glowOuter = material.GetFloat(ID_GlowOuter) * scaleRatio_B;
|
|||
|
}
|
|||
|
|
|||
|
uniformPadding = Mathf.Max(uniformPadding, faceDilate + glowOffset + glowOuter);
|
|||
|
|
|||
|
// Underlay padding contribution
|
|||
|
if (material.HasProperty(ID_UnderlaySoftness) && shaderKeywords.Contains(Keyword_Underlay)) // Generates GC
|
|||
|
{
|
|||
|
if (material.HasProperty(ID_ScaleRatio_C))
|
|||
|
scaleRatio_C = material.GetFloat(ID_ScaleRatio_C);
|
|||
|
|
|||
|
float offsetX = 0;
|
|||
|
float offsetY = 0;
|
|||
|
float dilate = 0;
|
|||
|
float softness = 0;
|
|||
|
|
|||
|
if (material.HasProperty(ID_UnderlayOffset))
|
|||
|
{
|
|||
|
Vector2 underlayOffset = material.GetVector(ID_UnderlayOffset);
|
|||
|
offsetX = underlayOffset.x;
|
|||
|
offsetY = underlayOffset.y;
|
|||
|
|
|||
|
dilate = material.GetFloat(ID_UnderlayDilate);
|
|||
|
softness = material.GetFloat(ID_UnderlaySoftness);
|
|||
|
}
|
|||
|
else if (material.HasProperty(ID_UnderlayOffsetX))
|
|||
|
{
|
|||
|
|
|||
|
offsetX = material.GetFloat(ID_UnderlayOffsetX) * scaleRatio_C;
|
|||
|
offsetY = material.GetFloat(ID_UnderlayOffsetY) * scaleRatio_C;
|
|||
|
dilate = material.GetFloat(ID_UnderlayDilate) * scaleRatio_C;
|
|||
|
softness = material.GetFloat(ID_UnderlaySoftness) * scaleRatio_C;
|
|||
|
}
|
|||
|
|
|||
|
padding.x = Mathf.Max(padding.x, faceDilate + dilate + softness - offsetX);
|
|||
|
padding.y = Mathf.Max(padding.y, faceDilate + dilate + softness - offsetY);
|
|||
|
padding.z = Mathf.Max(padding.z, faceDilate + dilate + softness + offsetX);
|
|||
|
padding.w = Mathf.Max(padding.w, faceDilate + dilate + softness + offsetY);
|
|||
|
}
|
|||
|
|
|||
|
padding.x = Mathf.Max(padding.x, uniformPadding);
|
|||
|
padding.y = Mathf.Max(padding.y, uniformPadding);
|
|||
|
padding.z = Mathf.Max(padding.z, uniformPadding);
|
|||
|
padding.w = Mathf.Max(padding.w, uniformPadding);
|
|||
|
|
|||
|
padding.x += extraPadding;
|
|||
|
padding.y += extraPadding;
|
|||
|
padding.z += extraPadding;
|
|||
|
padding.w += extraPadding;
|
|||
|
|
|||
|
padding.x = Mathf.Min(padding.x, 1);
|
|||
|
padding.y = Mathf.Min(padding.y, 1);
|
|||
|
padding.z = Mathf.Min(padding.z, 1);
|
|||
|
padding.w = Mathf.Min(padding.w, 1);
|
|||
|
|
|||
|
maxPadding.x = maxPadding.x < padding.x ? padding.x : maxPadding.x;
|
|||
|
maxPadding.y = maxPadding.y < padding.y ? padding.y : maxPadding.y;
|
|||
|
maxPadding.z = maxPadding.z < padding.z ? padding.z : maxPadding.z;
|
|||
|
maxPadding.w = maxPadding.w < padding.w ? padding.w : maxPadding.w;
|
|||
|
|
|||
|
gradientScale = material.GetFloat(ID_GradientScale);
|
|||
|
padding *= gradientScale;
|
|||
|
|
|||
|
// Set UniformPadding to the maximum value of any of its components.
|
|||
|
uniformPadding = Mathf.Max(padding.x, padding.y);
|
|||
|
uniformPadding = Mathf.Max(padding.z, uniformPadding);
|
|||
|
uniformPadding = Mathf.Max(padding.w, uniformPadding);
|
|||
|
|
|||
|
return uniformPadding + 1.25f;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static float ComputePaddingForProperties(Material mat)
|
|||
|
{
|
|||
|
Vector4 dilation = mat.GetVector(ID_IsoPerimeter);
|
|||
|
Vector2 outlineOffset1 = mat.GetVector(ID_OutlineOffset1);
|
|||
|
Vector2 outlineOffset2 = mat.GetVector(ID_OutlineOffset2);
|
|||
|
Vector2 outlineOffset3 = mat.GetVector(ID_OutlineOffset3);
|
|||
|
bool isOutlineModeEnabled = mat.GetFloat(ID_OutlineMode) != 0;
|
|||
|
|
|||
|
Vector4 softness = mat.GetVector(ID_Softness);
|
|||
|
float gradientScale = mat.GetFloat(ID_GradientScale);
|
|||
|
|
|||
|
// Face
|
|||
|
float padding = Mathf.Max(0, dilation.x + softness.x * 0.5f);
|
|||
|
|
|||
|
// Outlines
|
|||
|
if (!isOutlineModeEnabled)
|
|||
|
{
|
|||
|
padding = Mathf.Max(padding, dilation.y + softness.y * 0.5f + Mathf.Max(Mathf.Abs(outlineOffset1.x), Mathf.Abs(outlineOffset1.y)));
|
|||
|
padding = Mathf.Max(padding, dilation.z + softness.z * 0.5f + Mathf.Max(Mathf.Abs(outlineOffset2.x), Mathf.Abs(outlineOffset2.y)));
|
|||
|
padding = Mathf.Max(padding, dilation.w + softness.w * 0.5f + Mathf.Max(Mathf.Abs(outlineOffset3.x), Mathf.Abs(outlineOffset3.y)));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
float offsetOutline1 = Mathf.Max(Mathf.Abs(outlineOffset1.x), Mathf.Abs(outlineOffset1.y));
|
|||
|
float offsetOutline2 = Mathf.Max(Mathf.Abs(outlineOffset2.x), Mathf.Abs(outlineOffset2.y));
|
|||
|
|
|||
|
padding = Mathf.Max(padding, dilation.y + softness.y * 0.5f + offsetOutline1);
|
|||
|
padding = Mathf.Max(padding, dilation.z + softness.z * 0.5f + offsetOutline2);
|
|||
|
|
|||
|
float maxOffset = Mathf.Max(offsetOutline1, offsetOutline2);
|
|||
|
padding += Mathf.Max(0 ,(dilation.w + softness.w * 0.5f) - Mathf.Max(0, padding - maxOffset));
|
|||
|
}
|
|||
|
|
|||
|
// Underlay
|
|||
|
Vector2 underlayOffset = mat.GetVector(ID_UnderlayOffset);
|
|||
|
float underlayDilation = mat.GetFloat(ID_UnderlayDilate);
|
|||
|
float underlaySoftness = mat.GetFloat(ID_UnderlaySoftness);
|
|||
|
padding = Mathf.Max(padding, underlayDilation + underlaySoftness * 0.5f + Mathf.Max(Mathf.Abs(underlayOffset.x), Mathf.Abs(underlayOffset.y)));
|
|||
|
|
|||
|
return padding * gradientScale;
|
|||
|
}
|
|||
|
|
|||
|
// Function to determine how much extra padding is required as a result of material properties like dilate, outline thickness, softness, glow, etc...
|
|||
|
public static float GetPadding(Material[] materials, bool enableExtraPadding, bool isBold)
|
|||
|
{
|
|||
|
//Debug.Log("GetPadding() called.");
|
|||
|
|
|||
|
if (isInitialized == false)
|
|||
|
GetShaderPropertyIDs();
|
|||
|
|
|||
|
// Return if Material is null
|
|||
|
if (materials == null) return 0;
|
|||
|
|
|||
|
int extraPadding = enableExtraPadding ? 4 : 0;
|
|||
|
|
|||
|
// Check if we are using a Bitmap Shader
|
|||
|
if (materials[0].HasProperty(ID_Padding))
|
|||
|
return extraPadding + materials[0].GetFloat(ID_Padding);
|
|||
|
|
|||
|
Vector4 padding = Vector4.zero;
|
|||
|
Vector4 maxPadding = Vector4.zero;
|
|||
|
|
|||
|
float faceDilate = 0;
|
|||
|
float faceSoftness = 0;
|
|||
|
float outlineThickness = 0;
|
|||
|
float scaleRatio_A = 0;
|
|||
|
float scaleRatio_B = 0;
|
|||
|
float scaleRatio_C = 0;
|
|||
|
|
|||
|
float glowOffset = 0;
|
|||
|
float glowOuter = 0;
|
|||
|
|
|||
|
float uniformPadding = 0;
|
|||
|
// Iterate through each of the assigned materials to find the max values to set the padding.
|
|||
|
for (int i = 0; i < materials.Length; i++)
|
|||
|
{
|
|||
|
// Update Shader Ratios prior to computing padding
|
|||
|
ShaderUtilities.UpdateShaderRatios(materials[i]);
|
|||
|
|
|||
|
string[] shaderKeywords = materials[i].shaderKeywords;
|
|||
|
|
|||
|
if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_A))
|
|||
|
scaleRatio_A = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_A);
|
|||
|
|
|||
|
if (materials[i].HasProperty(ShaderUtilities.ID_FaceDilate))
|
|||
|
faceDilate = materials[i].GetFloat(ShaderUtilities.ID_FaceDilate) * scaleRatio_A;
|
|||
|
|
|||
|
if (materials[i].HasProperty(ShaderUtilities.ID_OutlineSoftness))
|
|||
|
faceSoftness = materials[i].GetFloat(ShaderUtilities.ID_OutlineSoftness) * scaleRatio_A;
|
|||
|
|
|||
|
if (materials[i].HasProperty(ShaderUtilities.ID_OutlineWidth))
|
|||
|
outlineThickness = materials[i].GetFloat(ShaderUtilities.ID_OutlineWidth) * scaleRatio_A;
|
|||
|
|
|||
|
uniformPadding = outlineThickness + faceSoftness + faceDilate;
|
|||
|
|
|||
|
// Glow padding contribution
|
|||
|
if (materials[i].HasProperty(ShaderUtilities.ID_GlowOffset) && shaderKeywords.Contains(ShaderUtilities.Keyword_Glow))
|
|||
|
{
|
|||
|
if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_B))
|
|||
|
scaleRatio_B = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_B);
|
|||
|
|
|||
|
glowOffset = materials[i].GetFloat(ShaderUtilities.ID_GlowOffset) * scaleRatio_B;
|
|||
|
glowOuter = materials[i].GetFloat(ShaderUtilities.ID_GlowOuter) * scaleRatio_B;
|
|||
|
}
|
|||
|
|
|||
|
uniformPadding = Mathf.Max(uniformPadding, faceDilate + glowOffset + glowOuter);
|
|||
|
|
|||
|
// Underlay padding contribution
|
|||
|
if (materials[i].HasProperty(ShaderUtilities.ID_UnderlaySoftness) && shaderKeywords.Contains(ShaderUtilities.Keyword_Underlay))
|
|||
|
{
|
|||
|
if (materials[i].HasProperty(ShaderUtilities.ID_ScaleRatio_C))
|
|||
|
scaleRatio_C = materials[i].GetFloat(ShaderUtilities.ID_ScaleRatio_C);
|
|||
|
|
|||
|
float offsetX = materials[i].GetFloat(ShaderUtilities.ID_UnderlayOffsetX) * scaleRatio_C;
|
|||
|
float offsetY = materials[i].GetFloat(ShaderUtilities.ID_UnderlayOffsetY) * scaleRatio_C;
|
|||
|
float dilate = materials[i].GetFloat(ShaderUtilities.ID_UnderlayDilate) * scaleRatio_C;
|
|||
|
float softness = materials[i].GetFloat(ShaderUtilities.ID_UnderlaySoftness) * scaleRatio_C;
|
|||
|
|
|||
|
padding.x = Mathf.Max(padding.x, faceDilate + dilate + softness - offsetX);
|
|||
|
padding.y = Mathf.Max(padding.y, faceDilate + dilate + softness - offsetY);
|
|||
|
padding.z = Mathf.Max(padding.z, faceDilate + dilate + softness + offsetX);
|
|||
|
padding.w = Mathf.Max(padding.w, faceDilate + dilate + softness + offsetY);
|
|||
|
}
|
|||
|
|
|||
|
padding.x = Mathf.Max(padding.x, uniformPadding);
|
|||
|
padding.y = Mathf.Max(padding.y, uniformPadding);
|
|||
|
padding.z = Mathf.Max(padding.z, uniformPadding);
|
|||
|
padding.w = Mathf.Max(padding.w, uniformPadding);
|
|||
|
|
|||
|
padding.x += extraPadding;
|
|||
|
padding.y += extraPadding;
|
|||
|
padding.z += extraPadding;
|
|||
|
padding.w += extraPadding;
|
|||
|
|
|||
|
padding.x = Mathf.Min(padding.x, 1);
|
|||
|
padding.y = Mathf.Min(padding.y, 1);
|
|||
|
padding.z = Mathf.Min(padding.z, 1);
|
|||
|
padding.w = Mathf.Min(padding.w, 1);
|
|||
|
|
|||
|
maxPadding.x = maxPadding.x < padding.x ? padding.x : maxPadding.x;
|
|||
|
maxPadding.y = maxPadding.y < padding.y ? padding.y : maxPadding.y;
|
|||
|
maxPadding.z = maxPadding.z < padding.z ? padding.z : maxPadding.z;
|
|||
|
maxPadding.w = maxPadding.w < padding.w ? padding.w : maxPadding.w;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
float gradientScale = materials[0].GetFloat(ShaderUtilities.ID_GradientScale);
|
|||
|
padding *= gradientScale;
|
|||
|
|
|||
|
// Set UniformPadding to the maximum value of any of its components.
|
|||
|
uniformPadding = Mathf.Max(padding.x, padding.y);
|
|||
|
uniformPadding = Mathf.Max(padding.z, uniformPadding);
|
|||
|
uniformPadding = Mathf.Max(padding.w, uniformPadding);
|
|||
|
|
|||
|
return uniformPadding + 0.25f;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|