Unity3D Shader实现流光效果
程序员文章站
2023-02-19 16:10:58
本文实例为大家分享了unity3d shader实现流光效果的具体代码,供大家参考,具体内容如下流光效果图:演示工程:下载地址//功能需求:模拟数据传送效果,高亮色块从模型上方移动到下方//功能分析:...
本文实例为大家分享了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" }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。