Text Outline

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(reverted to former colors outputs because default unity fonts color and generic sprites colors do not allow for mixed usage between texts and sprites)
(calculating the sqrt of a value to later on get the sqr of this value is stupid)
Line 118: Line 118:
 
                         if( min_dst < 1.0e38f )
 
                         if( min_dst < 1.0e38f )
 
                         {
 
                         {
                            fixed  dist  = sqrt( min_dst );
+
                             fixed  alpha = 1.0f - ( clamp( ( min_dst ) / ( _Thickness * _Thickness ), 0.0f, 1.0f ) );
                             fixed  alpha = 1.0f - ( clamp( ( dist * dist ) / ( _Thickness * _Thickness ), 0.0f, 1.0f ) );
+
 
                             return alpha;
 
                             return alpha;
 
                         }
 
                         }

Revision as of 14:07, 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  alpha = 1.0f - ( clamp( ( min_dst ) / ( _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