UnityShader3实现2D描边效果

本文实例为大家分享了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
    }
  }
}

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

(0)

相关推荐

  • Unity3D中shader 轮廓描边效果实现代码

    Unity3D中shader 轮廓描边效果 想利用Unity3D中shader这个功能实现描边轮廓边框效果该怎么做呢,相信有很多搞开发的人想知道,为此下面就给大家介绍下方法. Shade实现描边效果,如下图中的3D球效果图         Shade代码如下: Shader "Outlined/Silhouetted Diffuse" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _OutlineCo

  • UnityShader3实现2D描边效果

    本文实例为大家分享了UnityShader3实现2D描边效果的具体代码,供大家参考,具体内容如下 1. Shader "Custom/Edge" { Properties { _MainTex ("Texture", 2D) = "white" {} _OffsetUV ("OffsetUV", Range(0, 1)) = 0.1 _EdgeColor ("EdgeColor", Color) = (1,

  • jQuery插件FusionCharts实现的2D柱状图效果示例【附demo源码下载】

    本文实例讲述了jQuery插件FusionCharts实现的2D柱状图效果.分享给大家供大家参考,具体如下: 1.实现代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>FusionCharts最新FusionCharts2D柱状图</title> <script type="text/javascript" sr

  • jQuery插件HighCharts绘制2D饼图效果示例【附demo源码下载】

    本文实例讲述了jQuery插件HighCharts绘制2D饼图效果.分享给大家供大家参考,具体如下: 1.实例代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>HighCharts 2D饼图</title> <script type="text/javascript" src="js/jquery-1.

  • jQuery插件HighCharts绘制简单2D柱状图效果示例【附demo源码】

    本文实例讲述了jQuery插件HighCharts绘制简单2D柱状图效果.分享给大家供大家参考,具体如下: 1.实例代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>HighCharts 2D柱状图</title> <script type="text/javascript" src="js/jquer

  • UnityShader3实现彩光效果

    本文实例为大家分享了UnityShader3实现彩光效果展示的具体代码,供大家参考,具体内容如下 参考链接: [OpenGL]Shader实例分析(八)- 彩色光圈 效果图: 这里我把它分三部分实现:1.彩色 2.光圈 3.动画 1.先实现彩色效果.分析一下那张彩色图,它是以中心为原点的,然后颜色分为三部分,如下图.当角度为90度时,蓝色最多:当角度为-150度时,红色最多:当角度为-30度时,绿色最多.然后其他地方就是三色混合. Shader "Custom/Colors" { Pr

  • webgl实现物体描边效果的方法介绍

    前言 终于把手头的事结束了,可以有时间来研究研究技术~作为一名3D开发人员,仅仅使用现有的引擎来开发项目不免有些浮于表面,多研究研究底层的实现更利于对3D开发整体的把控~于是我决定最近开始研究webgl一些特效的实现,希望能在秋招前对底层有更深入的理解. 在webgl中实现描边的效果有很多种方式,比如我写卡通风格着色器那篇文章讲到的(将视线投影到每个点的法线上,这个值越小越说明这个点靠近边缘),所以接下来介绍实现的另一种方式:法线延展法. 这种方法不用进行法线与视线之间的计算,而是将物体每个点的

  • three.js利用卷积法如何实现物体描边效果

    法线延展法 网上使用法线延展法实现物体描边效果的文章比较多,这里不再描述. 但是这种方法有个缺点:当两个面的法线夹角差别较大时,两个面的描边无法完美连接.如下图所示: 卷积法 这里使用另一种方法卷积法实现物体描边效果,一般机器学习使用该方法比较多.先看效果图: 使用three.js具体的实现方法如下: 创建着色器材质,隐藏不需要描边的物体进行渲染,将需要描边的位置渲染成白色,其他位置渲染成黑色. 利用片源着色器计算卷积,白色是物体内部,黑色是物体外部,灰色是边框. 设置材质透明.不融合,将边框叠

  • Unity Shader实现2D水流效果

    水流的模拟主要运用了顶点变换和纹理动画的结合: 顶点变换中,利用正弦函数模拟河流的大致形态,例如波长,振幅等. 纹理动画中,将纹理坐标朝某一方向持续滚动以形成流动的效果. 脚本如下: Shader "MyUnlit/ScrollWater" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color("Color Tint",color)=(1,1,1,1) //控制

  • svg动画之动态描边效果

    1.首先先做一个简单的线一点一点画出来的效果,主要使用svg中的"strokeDasharray"."strokeDashoffset"属性,通过css3中的transtion改变strokeDashoffset来实现动画. 注:path中的数据通过在ai中划线后存储为svg格式就可以拿到: 效果图: 代码如下: <svg class="move_line1" xmlns="http://www.w3.org/2000/svg&q

随机推荐