成都创新互联网站制作重庆分公司

Unity3DShader如何实现流光效果-创新互联

这篇文章主要为大家展示了Unity3D Shader如何实现流光效果,内容简而易懂,希望大家可以学习一下,学习完之后肯定会有收获的,下面让小编带大家一起来看看吧。

成都创新互联是一家专业提供当涂企业网站建设,专注与成都网站制作、网站设计、H5建站、小程序制作等业务。10年已为当涂众多企业、政府机构等服务。创新互联专业的建站公司优惠进行中。

流光效果图:

Unity3D Shader如何实现流光效果

演示工程:下载地址

//功能需求:模拟数据传送效果,高亮色块从模型上方移动到下方
//功能分析:这里采用UV动画的方式来实现,利用Alpha贴图控制流动的形状
//  利用Alpha遮罩贴图,控制模型中哪些地方需要进行流动

Shader "Custom/DataFlowEffect"
{
 Properties
 {
 _MainColor("Main Color",Color) = (1,1,1,1)
 _MainTex("Main Texture",2D) = "white"{}
 _Specular("Specular",Color) = (1,1,1,1)
 _Gloss("Gloss",Range(0,255)) = 20.0
 _FlowTex("Flow Tex (A)",2D) = "black"{}
 _FlowColor("Flow Color (RGBA)",Color)=(1,1,1,1)
 _FlowIdleTime("FlowInternal",Range(0,10))=1.0
 _FlowDuring("FlowDuring",Range(0,10))=1.0
 _FlowMaskTex("FlowMasking (A)",2D)="white"{}
 _FlowDirection("FlowDirection",Int)= 0
 _FlowBeginTime("Flow Begin Time",Float)=0
 }

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

 Pass
 {
  Tags{"LightMode"="ForwardBase"}
  Blend SrcAlpha OneMinusSrcAlpha

  CGPROGRAM

  #pragma vertex vert
  #pragma fragment frag

  #include "UnityCG.cginc"
  #include "Lighting.cginc"

  sampler2D _MainTex; //颜色贴图
  half4 _MainTex_ST; //颜色UV 缩放和偏移
  fixed3 _MainColor; //漫反射颜色
  fixed3 _Specular; //高光颜色
  fixed _Gloss;  //高光度
  sampler2D _FlowTex; //数据流图片
  fixed4 _FlowColor; //数据流颜色叠加
  half4 _FlowTex_ST; //数据流贴图UV的缩放和偏移
  fixed _FlowIdleTime; //流动动画间歇时间
  fixed _FlowDuring; //流动动画播放时间
  sampler2D _FlowMaskTex; //流动遮罩
  fixed _FlowDirection; //流动方向
  float _FlowBeginTime; //流动效果开始的时间

  struct a2v
  {
  half4 pos: POSITION;
  half3 normal :NORMAL;
  half4 texcoord : TEXCOORD0;
  };

  struct v2f
  {
  half4 position : SV_POSITION;
  half2 uv : TEXCOORD0;
  half3 worldNormal : TEXCOORD1;
  half3 worldPos : TEXCOORD2;
  half2 flowUV : TEXCOORD3;
  };

  v2f vert(a2v i)
  {
  v2f v;
  v.position = UnityObjectToClipPos(i.pos);
  v.uv = i.texcoord * _MainTex_ST.xy + _MainTex_ST.zw;
  v.worldNormal = mul(unity_ObjectToWorld,i.normal);
  v.worldPos = mul(unity_ObjectToWorld,i.pos);
  v.flowUV = i.texcoord * _FlowTex_ST.xy + _FlowTex_ST.zw;
  return v;
  }

  //uv - vert的uv坐标
  //scale - 贴图缩放
  //idleTime - 每次循环开始后多长时间,开始流动
  //loopTime - 单次流动时间
  fixed4 getFlowColor(half2 uv,int scale,fixed idleTime,fixed loopTime)
  {
  //当前运行时间
  half flowTime_ = _Time.y - _FlowBeginTime;

  //上一次循环开始,到本次循环开始的时间间隔
  half internal = idleTime + loopTime;

  //当前循环执行时间
  half curLoopTime = fmod(flowTime_,internal);

  //每次开始流动之前,有个停止间隔,检测是否可以流动了
  if(curLoopTime > idleTime)
  {
   //已经流动时间
   half actionTime = curLoopTime - idleTime;

   //流动进度百分比
   half actionPercentage = actionTime / loopTime;

   half length = 1.0 / scale;

   //从下往上流动
   //计算方式:设:y = ax + b,其中y为下边界值,x为流动进度
   //根据我们要求可以,x=0时y=-length;x=1时y=1;带入解方程
   half bottomBorder = actionPercentage * (1+length) - length;
   half topBorder = bottomBorder + length;

   //从上往下流动
   //求解方法与上面类似
   if(_FlowDirection < 0)
   {
   topBorder = (-1-length) * actionPercentage + 1 + length;
   bottomBorder = topBorder - length;
   }

   if(uv.y < topBorder && uv.y > bottomBorder)
   {
   half y = (uv.y - bottomBorder) / length;
   return tex2D(_FlowTex,fixed2(uv.x,y)); 
   }
  }

  return fixed4(1,1,1,0);
  }

  fixed4 frag(v2f v):SV_Target
  {
  //计算漫反射系数
  fixed3 albedo = tex2D(_MainTex,v.uv) * _MainColor;

  //计算环境光
  fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;


  fixed3 worldNormal = normalize(v.worldNormal);    //世界坐标的法线方向
  fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(v.worldPos)); //世界坐标的光照方向
  fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(v.worldPos)); //世界坐标的视角方向

  //计算漫反射颜色,采用Half-Lambert模型
  fixed3 lightColor = _LightColor0.rgb;
  fixed3 diffuse = lightColor * albedo * max(0,0.5*dot(worldNormal,worldLightDir)+0.5);

  //计算高光,采用Blinn-Phone高光模型
  fixed3 halfDir = normalize(worldViewDir + worldLightDir);
  fixed3 specColor = _Specular * lightColor * pow(max(0,dot(worldNormal,halfDir)),_Gloss);

  //叠加流动贴图  
  fixed4 flowColor = getFlowColor(v.uv,_FlowTex_ST.y,_FlowIdleTime,_FlowDuring); 
  fixed4 flowMaskColor = tex2D(_FlowMaskTex,v.uv);

  //与遮罩贴图进行混合,只显示遮罩贴图不透明的部分
  flowColor.a = flowMaskColor.a * flowColor.a * _FlowColor.a;

  fixed3 finalDiffuse = lerp(diffuse,_FlowColor,flowColor.a);

  return fixed4(ambient + finalDiffuse+specColor,1);
  }

  ENDCG
 }
 }
 Fallback "Diffuse"
}

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章标题:Unity3DShader如何实现流光效果-创新互联
网页路径:http://cxhlcq.com/article/cciheo.html

其他资讯

在线咨询

微信咨询

电话咨询

028-86922220(工作日)

18980820575(7×24)

提交需求

返回顶部