Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Typogenic - Advanced Text Rendering [FREE]

Discussion in 'Assets and Asset Store' started by Chman, Jul 2, 2014.

  1. rlatapy

    rlatapy

    Joined:
    Feb 9, 2016
    Posts:
    10
    Hey!
    Thank a lot for your work. Having trouble with text in 3D space, I was looking for a solution using distance field technique.
    Everything works quite well, except when I move the text is far from camera. I try what you propose in tips & trick section from your doc. (mipmap, filetring etc), but it's not as efficient as if I do the same treatment on an image.
    Do you have any idea ?
     
  2. Gekigengar

    Gekigengar

    Joined:
    Jan 20, 2013
    Posts:
    706
    The asset store page is dead, but it has been updated to support Unity 5.0,
    Please re-upload to the Asset Store :D
     
  3. Good_Venson

    Good_Venson

    Joined:
    Oct 12, 2014
    Posts:
    22
    How would I use this with the UI system?
     
  4. M0rrigan

    M0rrigan

    Joined:
    May 29, 2015
    Posts:
    29
    Hello, I am using Typogenic for my project and I'm here to ask a few questions.
    1. I am currently using a script to get an array of Text component. However I get an error when I change the code to get the TypogenicText component, like this:
    Code (CSharp):
    1.             myText[i] = letters[i].GetComponent<TypogenicText>();
    The error: Cannot implicitly convert type `TypogenicText' to `UnityEngine.UI.Text'

    2. I don't have any experience with shaders, but I tried to add a Cull Back to render also the back of the text. I am using the TypogenicUnlitShadowCaster:

    Code (CSharp):
    1. Shader "Typogenic/Unlit Shadowcaster Font"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Base (Alpha8)", 2D) = "white" {}
    6.         _Smoothness ("Smoothness / Antialiasing (Float)", Float) = 0.85
    7.         _Thickness ("Thickness (Float)", Range(1.0, 0.05)) = 0.5
    8.  
    9.         // OUTLINED
    10.         _OutlineColor ("Outline Color (RGBA)", Color) = (0, 0, 0, 1)
    11.         _OutlineThickness ("Outline Thickness (Float)", Range(1.0, 0.1)) = 0.25
    12.  
    13.         // GLOW
    14.         _GlowColor ("Glow Color (RGBA)", Color) = (0, 0, 0, 1)
    15.         _GlowStart ("Glow Start", Range(0.0, 1.0)) = 0.1
    16.         _GlowEnd ("Glow End", Range(0.0, 1.0)) = 0.9
    17.  
    18.         // GLOBAL_MULTIPLIER
    19.         _GlobalMultiplierColor ("Global Color Multiplier (RGBA)", Color) = (1, 1, 1, 1)
    20.  
    21.         // SHADOW CUTOFF
    22.         _ShadowCutoff ("Shadow Cutoff",Range(0.01, 1.0)) = .7
    23.     }
    24.     SubShader
    25.     {
    26.         Pass {
    27.             Name "ShadowCaster"
    28.             Tags { "LightMode" = "ShadowCaster" "Queue"="AlphaTest" "RenderType"="TransparentCutout" }
    29.             Offset 1, 1
    30.          
    31.             Fog {Mode Off}
    32.             ZWrite On ZTest LEqual Cull Back
    33.  
    34.             CGPROGRAM
    35.             #pragma vertex vert
    36.             #pragma fragment frag
    37.             #pragma multi_compile OUTLINED_ON OUTLINED_OFF
    38.             #pragma multi_compile_shadowcaster
    39.             #pragma fragmentoption ARB_precision_hint_fastest
    40.             #include "UnityCG.cginc"
    41.          
    42.             float4 _MainTex_ST;
    43.             sampler2D _MainTex;
    44.             half _OutlineThickness;
    45.             half _ShadowCutoff;
    46.             half _Smoothness;
    47.             half _Thickness;
    48.  
    49.            
    50.             struct v2f {
    51.                 V2F_SHADOW_CASTER;
    52.                 float2  uv : TEXCOORD1;
    53.             };
    54.          
    55.             v2f vert( appdata_base v ) {
    56.                 v2f o;
    57.                 TRANSFER_SHADOW_CASTER(o)
    58.                 o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    59.                 return o;
    60.             }
    61.          
    62.             float4 frag(v2f i) : COLOR {
    63.                 half dist = tex2D(_MainTex, i.uv).a;
    64.                 half smoothing = fwidth(dist) * _Smoothness;
    65.                 half alpha = smoothstep(_Thickness - smoothing, _Thickness + smoothing, dist);
    66.                
    67.                 #if OUTLINED_ON
    68.                 half outlineAlpha = smoothstep(_OutlineThickness - smoothing, _OutlineThickness + smoothing, dist);
    69.                
    70.                 if (outlineAlpha > _ShadowCutoff)
    71.                 {
    72.                     alpha = outlineAlpha;
    73.                 }
    74.                 #endif
    75.                
    76.                 clip(alpha - _ShadowCutoff);
    77.              
    78.                 SHADOW_CASTER_FRAGMENT(i)
    79.             }
    80.             ENDCG
    81.         }
    82.    
    83.    
    84.    
    85.    
    86.         Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    87.         LOD 200
    88.         ZWrite Off
    89.  
    90.         Pass
    91.         {
    92.             Blend SrcAlpha OneMinusSrcAlpha
    93.  
    94.             CGPROGRAM
    95.             #pragma vertex vert
    96.             #pragma fragment frag
    97.             #pragma glsl
    98.             #pragma target 3.0
    99.             #pragma multi_compile OUTLINED_ON OUTLINED_OFF
    100.             #pragma multi_compile GLOW_ON GLOW_OFF
    101.             #pragma multi_compile GLOBAL_MULTIPLIER_ON GLOBAL_MULTIPLIER_OFF
    102.  
    103.             sampler2D _MainTex;
    104.             half _Smoothness;
    105.             half _Thickness;
    106.  
    107.             // OUTLINED
    108.             half4 _OutlineColor;
    109.             half _OutlineThickness;
    110.  
    111.             // GLOW
    112.             half4 _GlowColor;
    113.             half _GlowStart;
    114.             half _GlowEnd;
    115.            
    116.             // GLOBAL_MULTIPLIER
    117.             half4 _GlobalMultiplierColor;
    118.  
    119.             struct vertexInput
    120.             {
    121.                 half4 vertex : POSITION;
    122.                 half2 texcoord0 : TEXCOORD0;
    123.                 half4 color : COLOR;
    124.             };
    125.  
    126.             struct fragmentInput
    127.             {
    128.                 half4 position : SV_POSITION;
    129.                 half2 texcoord0 : TEXCOORD0;
    130.                 half4 color : COLOR;
    131.             };
    132.  
    133.             fragmentInput vert(vertexInput i)
    134.             {
    135.                 fragmentInput o;
    136.                 o.position = mul(UNITY_MATRIX_MVP, i.vertex);
    137.                 o.texcoord0 = i.texcoord0;
    138.                 o.color = i.color;
    139.                 return o;
    140.             }
    141.  
    142.             half4 frag(fragmentInput i) : COLOR
    143.             {
    144.                 half dist = tex2D(_MainTex, i.texcoord0).a;
    145.                 half smoothing = fwidth(dist) * _Smoothness;
    146.                 half alpha = smoothstep(_Thickness - smoothing, _Thickness + smoothing, dist);
    147.                 half4 finalColor = half4(i.color.rgb, i.color.a * alpha);
    148.  
    149.                 // OUTLINED
    150.                 #if OUTLINED_ON
    151.  
    152.                 half outlineAlpha = smoothstep(_OutlineThickness - smoothing, _OutlineThickness + smoothing, dist);
    153.                 half4 outline = half4(_OutlineColor.rgb, _OutlineColor.a * outlineAlpha);
    154.                 finalColor = lerp(outline, finalColor, alpha);
    155.  
    156.                 #endif
    157.  
    158.                 // GLOW
    159.                 #if GLOW_ON
    160.  
    161.                 half glowAlpha = smoothstep(_GlowStart, _GlowEnd, dist);
    162.                 finalColor = lerp(half4(_GlowColor.rgb, _GlowColor.a * glowAlpha), finalColor, finalColor.a);
    163.  
    164.                 #endif
    165.                
    166.                 // GLOBAL_MULTIPLIER
    167.                 #if GLOBAL_MULTIPLIER_ON
    168.  
    169.                 return finalColor * _GlobalMultiplierColor;
    170.  
    171.                 #endif
    172.  
    173.                 #if GLOBAL_MULTIPLIER_OFF
    174.  
    175.                 return finalColor;
    176.  
    177.                 #endif
    178.             }
    179.  
    180.             ENDCG
    181.         }
    182.     }
    183.  
    184.     FallBack off
    185.     CustomEditor "TypogenicMaterialEditor"
    186. }
    187.  
    I don't get any error, only a single-side text without shadow. So, clearly it doesn't work.

    3. I need to hide and display the text letter by letter. I am currently using the alpha color to do that, but with the Typogenic shader the shadow always remains on, even with the alpha = 0. Since I don't have any experience with shader can anybody help me with that?

    4. I don't think that Typogenic supports RichText, is there a way to add that?

    Thanks, any help will be much appreciated
     
  5. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    Regarding #1, TypogenicText is a Mesh type that is completely different from Unity's built-in UnityEngine.UI.Text, so you cannot "convert" it to that. You must assign the TypogenicText to a TypogenicText type.
     
  6. Chman

    Chman

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    721
    You could animate the text itself (the actual characters you type in the text area) to do a typewriter effect instead of trying to mess with the shader. It would be easier and faster.
    It does, sort of. See the doc.
     
  7. Deleted User

    Deleted User

    Guest

    Here are two additions that I had to make, in order to make Typogenic work as I needed:

    01. Justified alignment

    Like most text addons for Unity, you have only added support for the classic three (left, right and center) alignments. I have added two additional settings (justified and justified-strict). The image below show two simple implementations of these. On top of this implementation, I also added some improvements, that affects the spacing between characters, if the word spacing becomes too large. But the method of character spacing is not without debate, so it is not added initially, in the PullRequest. Below is three images, first the normal left alignment, then the justified alignment and finally the justified strict alignment (which is nearly the same).


    02. Clickable text

    As much as I appreciate the current clicking implementation, it has two major drawbacks. First of all, it is really hard to use on a phone, where your (butter) fingers do not have the same precision, as I would with a mouse. Half the time, my clicks ended up being just outside of the bounds, and registering as not hitting anything. Secondly, the current implementation has no 'early out' feature. It has to iterate through the entire text to determine the click, even if the click position is right at the beginning of the text, meaning that there's a significant unneeded performance cost with each click, in fact a O(CharacterCount) in complexity. I have added a radically different approach to clicking, one that suited my needs better; although the early-out could be implemented in the current version as well. I needed words to be clickable, so I marked words up with a rich-text similar formatting, what sentences should be clickable, and it splits that into words along with some additional padding around the total bound, for easier clicking. In the following image, the green bounds are the current implementations clickable area, and the red boxes are my word-click approach. This has a complexity of O(ClickableWords). Plus it solves what I call, the "Butter-finger problem". Although it should be said that if you need the entire text clickable on a per-character basis, this is not the solution for you.



     
    Last edited by a moderator: Jul 17, 2018