首页 > 编程 > C# > 正文

UnityShader3实现2D描边效果

2020-01-24 00:09:21
字体:
来源:转载
供稿:网友

本文实例为大家分享了UnityShader3实现2D描边效果的具体代码,供大家参考,具体内容如下

1.

Shader "Custom/Edge"{ Properties { _MainTex ("Texture", 2D) = "white" {} _OffsetUV ("OffsetUV", Range(0, 1)) = 0.1 _EdgeColor ("EdgeColor", Color) = (1, 0, 0, 1) _AlphaTreshold ("Treshold", Range(0, 1)) = 0.5  } SubShader { Tags { "Queue" = "Transparent" } Blend SrcAlpha OneMinusSrcAlpha  Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc"  struct appdata { float4 vertex : POSITION; fixed2 uv : TEXCOORD0; };  struct v2f {  float4 vertex : SV_POSITION; fixed2 uv[5] : TEXCOORD0; };  sampler2D _MainTex; float4 _MainTex_ST; fixed _OffsetUV; fixed4 _EdgeColor; fixed _AlphaTreshold;  v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);  o.uv[0] = v.uv;     o.uv[1] = v.uv + fixed2(0, _OffsetUV); //up     o.uv[2] = v.uv + fixed2(-_OffsetUV, 0); //left     o.uv[3] = v.uv + fixed2(0, -_OffsetUV); //bottom     o.uv[4] = v.uv + fixed2(_OffsetUV, 0); //right   return o; }  fixed4 frag (v2f i) : SV_Target { fixed4 original = tex2D(_MainTex, i.uv[0]);     fixed alpha = original.a;     fixed p1 = tex2D(_MainTex, i.uv[1]).a;     fixed p2 = tex2D(_MainTex, i.uv[2]).a;     fixed p3 = tex2D(_MainTex, i.uv[3]).a;     fixed p4 = tex2D(_MainTex, i.uv[4]).a;       alpha = p1 + p2 + p3 + p4 + alpha;     alpha /= 5;      if (alpha < _AlphaTreshold) original.rgb = _EdgeColor.rgb;       return original;  } ENDCG } }}

2.

Shader "Custom/Edge"{ Properties { _Edge ("Edge", Range(0, 0.2)) = 0.043 _EdgeColor ("EdgeColor", Color) = (1, 1, 1, 1) _MainTex ("MainTex", 2D) = "white" {} } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc"  fixed _Edge; fixed4 _EdgeColor; sampler2D _MainTex;  struct appdata { float4 vertex : POSITION; fixed2 uv : TEXCOORD0; };  struct v2f { float4 vertex : SV_POSITION; float4 objVertex : TEXCOORD0; fixed2 uv : TEXCOORD1; };  v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.objVertex = v.vertex; o.uv = v.uv;  return o; }  fixed4 frag (v2f i) : SV_Target {  fixed x = i.uv.x; fixed y = i.uv.y;   if((x < _Edge) || (abs(1 - x) < _Edge) || (y < _Edge) || (abs(1 - y) < _Edge))  {  return _EdgeColor * abs(cos(_Time.y)); } else  {  fixed4 color = tex2D(_MainTex, i.uv);  return color; }  //return i.objVertex; //return fixed4(i.uv, 0, 1); } ENDCG } }}

3.如下图,左边是一个Image,右边是一个Plane。

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Custom/Edge" {  Properties  {   _Edge ("Edge", Range(0, 0.2)) = 0.043   _EdgeColor ("EdgeColor", Color) = (1, 1, 1, 1)  _FlowColor ("FlowColor", Color) = (1, 1, 1, 1)  _FlowSpeed ("FlowSpeed", Range(0, 10)) = 3 _MainTex ("MainTex", 2D) = "white" {}  }  SubShader  {  Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" }    Pass   {  ZWrite Off  Blend SrcAlpha OneMinusSrcAlpha     CGPROGRAM    #pragma vertex vert    #pragma fragment frag    #include "UnityCG.cginc"     fixed _Edge;    fixed4 _EdgeColor;  fixed4 _FlowColor; float _FlowSpeed; sampler2D _MainTex;    struct appdata    {     float4 vertex : POSITION;     fixed2 uv : TEXCOORD0;    };     struct v2f    {     float4 vertex : SV_POSITION;     fixed2 uv : TEXCOORD1;    };     v2f vert (appdata v)    {     v2f o;     o.vertex = UnityObjectToClipPos(v.vertex);     o.uv = v.uv;     return o;    }        fixed4 frag (v2f i) : SV_Target    {      fixed x = i.uv.x;     fixed y = i.uv.y;      if((x < _Edge) || (abs(1 - x) < _Edge) || (y < _Edge) || (abs(1 - y) < _Edge))     {   //点旋转公式:  //假设对图片上任意点(x,y),绕一个坐标点(rx0,ry0)逆时针旋转a角度后的新的坐标设为(x0,y0),有公式:  //x0 = (x - rx0) * cos(a) - (y - ry0) * sin(a) + rx0 ;  //y0 = (x - rx0) * sin(a) + (y - ry0) * cos(a) + ry0 ;   float a = _Time.y * _FlowSpeed;   float2 rotUV;   x -= 0.5;  y -= 0.5;  rotUV.x = x * cos(a) - y * sin(a) + 0.5;  rotUV.y = x * sin(a) + y * cos(a) + 0.5;    fixed temp = saturate(rotUV.x - 0.5);//-0.5作用是调整流动颜色的比例     return _EdgeColor * (1 - temp) + _FlowColor * temp;    }     else     {      //fixed4 color = tex2D(_MainTex, i.uv);      return fixed4(1, 1, 1, 0);     }    }    ENDCG   }  } } 

4.通过观察上面的效果图,会发现右边的Plane出现了锯齿。而解决锯齿一般的方法就是做模糊处理,模糊处理一般又有贴图处理和代码处理之分,这里使用的是贴图处理。贴图处理需要提供一张边界模糊的贴图。

如上图,左下是内边反锯齿的图,右上是未经处理的图。

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'  Shader "Custom/Edge2" {  Properties  {   _Edge ("Edge", Range(0, 0.2)) = 0.043   _EdgeColor ("EdgeColor", Color) = (1, 1, 1, 1)   _FlowColor ("FlowColor", Color) = (1, 1, 1, 1)   _FlowSpeed ("FlowSpeed", Range(0, 10)) = 3   _MainTex ("MainTex", 2D) = "white" {}  }  SubShader  {   Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" }    Pass   {    ZWrite Off    Blend SrcAlpha OneMinusSrcAlpha     CGPROGRAM    #pragma vertex vert    #pragma fragment frag    #include "UnityCG.cginc"     fixed _Edge;    fixed4 _EdgeColor;    fixed4 _FlowColor;    float _FlowSpeed;    sampler2D _MainTex;     struct appdata    {     float4 vertex : POSITION;     fixed2 uv : TEXCOORD0;    };     struct v2f    {     float4 vertex : SV_POSITION;     fixed2 uv : TEXCOORD1;    };     v2f vert (appdata v)    {     v2f o;     o.vertex = UnityObjectToClipPos(v.vertex);      o.uv = v.uv;     return o;    }        fixed4 frag (v2f i) : SV_Target    {     fixed4 color = tex2D(_MainTex, i.uv); float alpha = color.a;  fixed x = i.uv.x;     fixed y = i.uv.y;  float a = _Time.y * _FlowSpeed;     float2 rotUV;      x -= 0.5;     y -= 0.5;     rotUV.x = x * cos(a) - y * sin(a) + 0.5;     rotUV.y = x * sin(a) + y * cos(a) + 0.5;           fixed temp = saturate(rotUV.x - 0.5);//-0.5作用是调整流动颜色的比例  fixed4 finalColor = _EdgeColor * (1 - temp) + _FlowColor * temp;    finalColor.a = alpha; return finalColor;    }    ENDCG   }  } } 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表