Text Outline
(the global alpha dicted by material color must pilot the alpha of the outline) |
m (material global alpha must pilot interior outline alpha + replaced outline color transition with appropriate lerp) |
||
Line 157: | Line 157: | ||
{ | { | ||
fixed alpha = GetOutineAlpha( i, output.a, false ); | fixed alpha = GetOutineAlpha( i, output.a, false ); | ||
− | if( alpha > 0.0f ) return | + | if( alpha > 0.0f ) return lerp( i.color, _OutlineColor, alpha ) * i.color.a; |
} | } | ||
Revision as of 14:00, 15 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
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 ) { fixed alpha = GetOutineAlpha( i, output.a, true ); if( alpha > 0.0f ) return fixed4( _OutlineColor.r, _OutlineColor.g, _OutlineColor.b, alpha * i.color.a ); } if( _Interior ) { fixed alpha = GetOutineAlpha( i, output.a, false ); if( alpha > 0.0f ) return lerp( i.color, _OutlineColor, alpha ) * i.color.a; } return output.a * i.color; } ENDCG } } }
License
Well, it's one of my first shaders, so... . Planet free.