Text Outline

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(correct exterior outline color accounting for every alphas sources)
(reverted to former colors outputs because default unity fonts color and generic sprites colors do not allow for mixed usage between texts and sprites)
Line 158: Line 158:
 
                         fixed  outline_alpha  = GetOutineAlpha( i, output.a, false );
 
                         fixed  outline_alpha  = GetOutineAlpha( i, output.a, false );
 
                         fixed4 material_color = fixed4( i.color.r, i.color.g, i.color.b, 1.0f );
 
                         fixed4 material_color = fixed4( i.color.r, i.color.g, i.color.b, 1.0f );
                         if( outline_alpha > 0.0f ) return lerp( output * material_color, _OutlineColor, outline_alpha ) * i.color.a;
+
                         if( outline_alpha > 0.0f ) return lerp( material_color, _OutlineColor, outline_alpha ) * i.color.a;
 
                     }
 
                     }
 
                      
 
                      
                     return output * i.color;
+
                     return output.a * i.color;
 
                 }
 
                 }
  

Revision as of 07:34, 16 October 2020

Author: Serge Billault

Contents

Description

Text outlining with independantly selectable interior and exterior. The pixel being rendered sample its surrounding according to outline _Thickness (in pixels) and deduce the outline alpha from the distance with the nearest outline inducing texture texel.

Preview

Text outline.jpg


Code ( UI_TextOutline.shader )

Invalid language.

You need to specify a language like this: <source lang="html4strict">...</source>

Supported languages for syntax highlighting:

4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, algol68, apache, applescript, apt_sources, asm, asp, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_loadrunner, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, coffeescript, cpp, cpp-qt, csharp, css, cuesheet, d, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, f1, falcon, fo, fortran, freebasic, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, j, java, java5, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, newlisp, nsis, oberon2, objc, objeck, ocaml, ocaml-brief, oobas, oracle11, oracle8, oxygene, oz, pascal, pcre, per, perl, perl6, pf, php, php-brief, pic16, pike, pixelbender, pli, plsql, postgresql, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, python, q, qbasic, rails, rebol, reg, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, sql, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, uscript, vala, vb, vbnet, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xorg_conf, xpp, yaml, z80, zxbasic


Shader "Unlit/UI_TextOutline"
{
    Properties
    {
                                              _MainTex     ( " Texture",       2D                 ) = "white" {}
        /*[PerRendererData]*/                 _OutlineColor( " Outline Color", Color              ) = ( 0.0, 0.0, 0.0, 1.0 )
        /*[PerRendererData]*/                 _Thickness   ( " Thickness",     Range( 1.0, 16.0 ) ) = 2.1
        /*[PerRendererData]*/[MaterialToggle] _Exterior    ( " Exterior", Float ) = 1.0
        /*[PerRendererData]*/[MaterialToggle] _Interior    ( " Interior", Float ) = 0.0
    }

    SubShader
    {
        Tags 
        { 
            "Queue"      = "Transparent"
            "RenderType" = "Opaque"
        }

        LOD 100

        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM

                //********************************************************************************************
                //
                //********************************************************************************************

                #pragma vertex   vert
                #pragma fragment frag

                #include "UnityCG.cginc"

                //********************************************************************************************
                //
                //********************************************************************************************

                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv     : TEXCOORD0;
                    float4 color  : COLOR;
                };

                struct v2f
                {
                    float4 vertex : SV_POSITION;
                    float2 uv     : TEXCOORD0;
                    float4 color  : COLOR;
                };

                static const fixed alpha_threshold = 0.6f;

                //********************************************************************************************
                //
                //********************************************************************************************

                sampler2D _MainTex;
                fixed4    _MainTex_TexelSize;
                fixed4    _MainTex_ST;
                fixed4    _OutlineColor;
                fixed     _Thickness;
                fixed     _Exterior;
                fixed     _Interior;

                //********************************************************************************************
                //
                //********************************************************************************************

                fixed GetOutineAlpha( v2f i, fixed a, bool exterior )
                {
                    bool valid_context = exterior ? ( a < alpha_threshold ) : ( a > alpha_threshold );
                    if ( valid_context )
                    {
                        fixed  texel_w = _MainTex_TexelSize.x;
                        fixed  texel_h = _MainTex_TexelSize.y;
                        fixed  min_dst = 1.0e38f;
                        fixed  dst;
                        fixed2 uv;
                        fixed4 sampling;

                        for( int x = -_Thickness; x <= _Thickness; ++x )
                        {
                            for( int y = -_Thickness; y <= _Thickness; ++y )
                            {
                                uv.x     = i.uv.x + ( x * texel_w );
                                uv.y     = i.uv.y + ( y * texel_h );
                                sampling = tex2Dlod( _MainTex, fixed4( uv.x, uv.y, 0, 0 ) );


                                bool outline = exterior ? ( sampling.a >= alpha_threshold ) : ( sampling.a <= alpha_threshold );
                                if ( outline )
                                {
                                    dst = ( x * x ) + ( y * y );
                                    if( min_dst > dst ) min_dst = dst; 
                                }
                            }
                        }
                        
                        if( min_dst < 1.0e38f )
                        {
                            fixed  dist  = sqrt( min_dst );
                            fixed  alpha = 1.0f - ( clamp( ( dist * dist ) / ( _Thickness * _Thickness ), 0.0f, 1.0f ) );
                            return alpha;
                        }
                    }

                    return -1.0f;
                }

                //********************************************************************************************
                //
                //********************************************************************************************

                v2f vert( appdata v )
                {
                    v2f o;
                    o.vertex = UnityObjectToClipPos( v.vertex );
                    o.uv     = TRANSFORM_TEX( v.uv, _MainTex );
                    o.color  = v.color;
                    return o;
                }

                //********************************************************************************************
                //
                //********************************************************************************************

                fixed4 frag( v2f i ) : SV_Target
                {
                    fixed4 output = tex2D( _MainTex, i.uv );

                    if( _Exterior > 0.0f )
                    {
                        fixed outline_alpha = GetOutineAlpha( i, output.a, true  );
                        if( outline_alpha > 0.0f ) return fixed4( _OutlineColor.r, _OutlineColor.g, _OutlineColor.b, _OutlineColor.a * outline_alpha * i.color.a );
                    }

                    if( _Interior > 0.0f )
                    {
                        fixed  outline_alpha  = GetOutineAlpha( i, output.a, false );
                        fixed4 material_color = fixed4( i.color.r, i.color.g, i.color.b, 1.0f );
                        if( outline_alpha > 0.0f ) return lerp( material_color, _OutlineColor, outline_alpha ) * i.color.a;
                    }
                    
                    return output.a * i.color;
                }

            ENDCG
        }
    }
}

License

Well, it's one of my first shaders, so... . Planet free.

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox