知了博客

集天地之精华,吸日月之灵气

« Unity Shader编程之-Unity Shader常用函数列表3D动画基础 »

Shader 进度条/技能CD特效

用了几天弄明白了这个简单的进度条,不容易。

主要是利用了三角函数反正切函数特性,在夹角范围内的值透明度设为0,不在范围内值设成1.

对于shader 编辑器,可以用forge 以及amplify.

贴上测试代码:

// Made with Amplify Shader Editor

// Available at the Unity Asset Store - http://u3d.as/y3X 

Shader "Unlit/MT"

{

Properties

{

_MainTex ("Sprite Texture", 2D) = "white" {}

_Color ("Tint", Color) = (1,1,1,1)

_angle("angle", Float) = 360

 

_StencilComp ("Stencil Comparison", Float) = 8

_Stencil ("Stencil ID", Float) = 0

_StencilOp ("Stencil Operation", Float) = 0

_StencilWriteMask ("Stencil Write Mask", Float) = 255

_StencilReadMask ("Stencil Read Mask", Float) = 255

 

_ColorMask ("Color Mask", Float) = 15

 

[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0

 

}

 

SubShader

{

Tags

"Queue"="Transparent"

"IgnoreProjector"="True"

"RenderType"="Transparent"

"PreviewType"="Plane"

"CanUseSpriteAtlas"="True"

}

Stencil

{

Ref [_Stencil]

Comp [_StencilComp]

Pass [_StencilOp] 

ReadMask [_StencilReadMask]

WriteMask [_StencilWriteMask]

}

 

Cull Off

Lighting Off

ZWrite Off

ZTest [unity_GUIZTestMode]

Blend SrcAlpha OneMinusSrcAlpha

ColorMask [_ColorMask]

 

 

Pass

{

Name "Default"

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#pragma target 2.0

 

#include "UnityCG.cginc"

#include "UnityUI.cginc"

 

#pragma multi_compile __ UNITY_UI_ALPHACLIP

 

struct appdata_t

{

float4 vertex   : POSITION;

float4 color    : COLOR;

float2 texcoord : TEXCOORD0;

};

 

struct v2f

{

float4 vertex   : SV_POSITION;

fixed4 color    : COLOR;

half2 texcoord  : TEXCOORD0;

float4 worldPosition : TEXCOORD1;

};

uniform fixed4 _Color;

uniform fixed4 _TextureSampleAdd;

uniform float4 _ClipRect;

uniform sampler2D _MainTex;

uniform float _angle;

v2f vert( appdata_t IN  )

{

v2f OUT;

OUT.worldPosition = IN.vertex;

OUT.worldPosition.xyz +=  float3( 0, 0, 0 ) ;

OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);

 

OUT.texcoord = IN.texcoord;

#ifdef UNITY_HALF_TEXEL_OFFSET

OUT.vertex.xy += (_ScreenParams.zw-1.0) * float2(-1,1) * OUT.vertex.w;

#endif

OUT.color = IN.color * _Color;

return OUT;

}

 

fixed4 frag(v2f IN  ) : SV_Target

{

half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;

float2 uv = IN.worldPosition.xy - float2(0.5,0.5);  

float  ang  = degrees(atan2(-uv.x,-uv.y))  + 180;   

//color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);

color.a *= saturate((ang -_angle));

#ifdef UNITY_UI_ALPHACLIP

clip (color.a - 0.001);

#endif

 

return color;

}

ENDCG

}

}

}/*ASEBEGIN

Version=13101

-116;157;1203;692;-46.31354;498.8189;1;True;True

Node;AmplifyShaderEditor.VertexToFragmentNode;29;541.0544,-68.96652;Float;False;1;0;COLOR;0.0;False;1;COLOR

Node;AmplifyShaderEditor.TemplateShaderPropertyNode;26;297.6875,-356.4916;Float;False;_TextureSampleAdd;0;1;FLOAT4

Node;AmplifyShaderEditor.RangedFloatNode;31;558.3135,-433.8189;Float;False;Property;_angle;angle;2;0;0;0;360;0;1;FLOAT

Node;AmplifyShaderEditor.SimpleMultiplyOpNode;23;65.14954,-236.1854;Float;False;2;2;0;FLOAT;0.0;False;1;FLOAT;0.0;False;1;FLOAT

Node;AmplifyShaderEditor.RangedFloatNode;21;-297.8843,-0.2657361;Float;False;Property;_Float1;Float 1;0;0;1;0;1;0;1;FLOAT

Node;AmplifyShaderEditor.VertexColorNode;30;307.9329,-207.2095;Float;True;0;5;COLOR;FLOAT;FLOAT;FLOAT;FLOAT

Node;AmplifyShaderEditor.RangedFloatNode;20;-306.7811,-256.8852;Float;False;Property;_Float0;Float 0;0;0;1;0;1;0;1;FLOAT

Node;AmplifyShaderEditor.TemplateShaderPropertyNode;28;797.5407,-125.9253;Float;False;_MainTex;0;1;SAMPLER2D

Node;AmplifyShaderEditor.TemplateMasterNode;19;635.5049,-337.8733;Float;False;True;2;Float;ASEMaterialInspector;0;3;Unlit/MT;5056123faa0c79b47ab6ad7e8bf059a4;2;0;FLOAT4;0,0,0,0;False;1;FLOAT3;0,0,0;False;0

WireConnection;29;0;30;0

WireConnection;23;0;20;0

WireConnection;23;1;21;0

ASEEND*/

//CHKSM=DF3770DDB144812ECE4D05E6DD7C43AB6637926F

 

 

 

 

参考:1 https://blog.csdn.net/u014761712/article/details/54882184

进度条shader 如下,创建三层Ui,第一层是外层蓝色,里层是那一个半透明的层,中间是那个绿色进度条添加下面的shader 的材质。通过外部设置shader “_Angle” 参数的改变来控制进度条。 
这里写图片描述

求反正切的函数atan(double x)与atan2(double y,double x) 他们返回的值是弧度 要转化为角度再自己处理下。

前者接受的是一个正切值(直线的斜率)得到夹角,但是由于正切的规律性本可以有两个角度的但它却只返回一个,因为atan的值域是从-90~90 也就是它只处理一四象限,所以一般不用它。

第二个atan2(double y,double x) 其中y代表已知点的Y坐标 同理x ,返回值是此点与远点连线与x轴正方向的夹角,这样它就可以处理四个象限的任意情况了,它的值域相应的也就是-180~180了

例如:

1:斜率是1的直线的夹角  cout<<atan(1.0)*180/PI;//45°  cout<<atan2(1.0,1.0)*180/PI;//45° 第一象限  cout<<atan2(-1.0,-1.0)*180/PI;//-135°第三象限  后两个斜率都是1 但是atan只能求出一个45°  例2:斜率是-1的直线的角度  cout<<atan(-1.0)*180/PI;//-45°  cout<<atan2(-1.0,1.0)*180/PI;//-45° y为负 在第四象限  cout<<atan2(1.0,-1.0)*180/PI;//135° x为负 在第二象限    常用的不是求过原点的直线的夹角 往往是求一个线段的夹角 这对于atan2就更是如鱼得水了  例如求A(1.0,1.0) B(3.0,3.0)这个线段AB与x轴正方向的夹角  用atan2表示为 atan2(y2-y1,x2-x1) 即 atan2(3.0-1.0,3.0-1.0)  它的原理就相当于把A点平移到原点B点相应变成B'(x2-x1,y2-y1)点 这样就又回到先前了  例三:  A(0.0,5.0) B(5.0,10.0)  线段AB的夹角为  cout<<atan2(5.0,5.0)*180/PI;//45°
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
Shader "UIEffect/uGUI_rand360" {     Properties     {         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}         _Color ("Tint", Color) = (1,1,1,1)         _Angle ("Angle", float) = 360         _Center ("Center", vector) = (.5,.5,0,0)         _Width ("Width", float) = 1         _AngleOffset("AngleOffset", float) = 0         [Toggle(CLOCK_WISE)]_ClockWise("ClockWise", float) = 1          _StencilComp ("Stencil Comparison", Float) = 8         _Stencil ("Stencil ID", Float) = 0         _StencilOp ("Stencil Operation", Float) = 0         _StencilWriteMask ("Stencil Write Mask", Float) = 255         _StencilReadMask ("Stencil Read Mask", Float) = 255          _ColorMask ("Color Mask", Float) = 15     }      SubShader     {         Tags         {             "Queue"="Transparent"             "IgnoreProjector"="True"             "RenderType"="Transparent"             "PreviewType"="Plane"             "CanUseSpriteAtlas"="True"         }          Stencil         {             Ref [_Stencil]             Comp [_StencilComp]             Pass [_StencilOp]             ReadMask [_StencilReadMask]             WriteMask [_StencilWriteMask]         }          Cull Off         Lighting Off         ZWrite Off         ZTest [unity_GUIZTestMode]         Blend SrcAlpha OneMinusSrcAlpha         ColorMask [_ColorMask]          Pass         {         CGPROGRAM             #pragma vertex vert             #pragma fragment frag             #pragma shader_feature CLOCK_WISE              #include "UnityCG.cginc"             #include "UnityUI.cginc"              float _Angle;             float4 _Center;             float _AngleOffset;              half _Width;              struct appdata_t             {                 float4 vertex   : POSITION;                 float4 color    : COLOR;                 float2 texcoord : TEXCOORD0;             };              struct v2f             {                 float4 vertex   : SV_POSITION;                 fixed4 color    : COLOR;                 half2 texcoord  : TEXCOORD0;                 float4 worldPosition : TEXCOORD1;             };              fixed4 _Color;             fixed4 _TextureSampleAdd;              bool _UseClipRect;             float4 _ClipRect;              bool _UseAlphaClip;              v2f vert(appdata_t IN)             {                 v2f OUT;                 OUT.worldPosition = IN.vertex;                 OUT.vertex = mul(UNITY_MATRIX_MVP, OUT.worldPosition);                  OUT.texcoord = IN.texcoord;                  #ifdef UNITY_HALF_TEXEL_OFFSET                 OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);                 #endif                  OUT.color = IN.color * _Color;                 return OUT;             }              sampler2D _MainTex;              fixed4 frag(v2f IN) : SV_Target             {                 half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;                  float2 pos = IN.texcoord.xy - _Center.xy;                 float x = pos.x;                 #ifdef CLOCK_WISE                 x = -x;                 #endif                 //float ang = degrees(atan2(x, -pos.y)) + 180;                 float ang = degrees(atan2(x, -pos.y)) + 180;                 color.a = color.a * saturate((ang - _Angle )/_Width);                    return color;             }         ENDCG         }     }        FallBack "Custom/Color Texture"    }

参考2:http://www.it610.com/article/3578678.htm

 

摘要:  技能CD特效 这个效果主要是利用反正切函数完成。atan2(x,y)的返回值是[-PI,PI],这个支持4个象限的反正切函数。关于圆角计算,在上篇文章中有介绍。现在,我们来看看反正切函数的效果:在第一象限:返回[0,PI/2],有渐变;在第二象限:返回[PI/2,PI],为白色;在第三象限:返回[-PI,-PI/2],为黑色;在第四象限:返回[-PI/2,0],为黑色;uv=i.uv-fixed

 

 

技能CD特效 

  这个效果主要是利用反正切函数完成。atan2(x,y)的返回值是[-PI,PI],这个支持4个象限的反正切函数。关于圆角计算,在上篇文章中有介绍。

  技能CD 效果 shader_第1张图片

  现在,我们来看看反正切函数的效果:

  技能CD 效果 shader_第2张图片

  在第一象限:返回[0,PI/2],有渐变;  

  在第二象限:返回[PI/2,PI],为白色;

  在第三象限:返回[-PI,-PI/2],为黑色;

  在第四象限:返回[-PI/2,0],为黑色;

  

                uv = i.uv - fixed2(0.5,0.5);                  float hui = atan2(uv.y, uv.x);                 return float4(hui,hui,hui,alpha);

 

  反正切的返回值在[-PI,PI],那么我们现在增加变量_angle,让他控制反正切的值;我们设置_angle值为[-PI,PI],用_angle的值,加上反正切的值,他们最后的值就会随着_angle的值变化。

    当_angle = -PI时,最终值为[-2PI,0],显示黑色;

    当_angle = PI时,最终值为[0,2PI],显示渐变;

    技能CD 效果 shader_第3张图片

  现在我使用用sign函数,将大于0的部分全部设置为1,小于等于0的部分设置成为0;

    技能CD 效果 shader_第4张图片

 

源代码:

Shader "JQM/Test02" {     Properties     {         _MainTex ("Texture", 2D) = "white" {}         _angle("angle", Range(0, 1)) = 0       }     SubShader     {          Pass         {             Tags {"Queue" = "Transparent"}                    ZWrite Off                    Blend SrcAlpha OneMinusSrcAlpha                  CGPROGRAM             #pragma vertex vert            #pragma fragment frag                          #include "UnityCG.cginc"            float _percent;               float _angle;                sampler2D _MainTex;             float4 _MainTex_ST;              struct VertexOutPut             {                 float4 pos : SV_POSITION;                 float2 uv : TEXCOORD0;             };                          VertexOutPut vert (appdata_full v)             {                 VertexOutPut o;                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);                     o.uv = v.texcoord.xy;                    return o;             }                          fixed4 frag (VertexOutPut i) : COLOR             {                 //圆角计算                float2 uv = i.uv.xy - float2(0.5,0.5);                     float rx = fmod(uv.x, 0.4);                      float ry = fmod(uv.y, 0.4);                      float mx = step(0.4, abs(uv.x));                   float my = step(0.4, abs(uv.y));                   float alpha = 1 - mx*my*step(0.1, length(half2(rx,ry)));                    fixed4 col = tex2D(_MainTex, i.uv);                         uv = i.uv - fixed2(0.5,0.5);                   _angle = 6.283*(_angle-0.5);                  float hui =sign(_angle+atan2(uv.y, uv.x));                 return float4(hui,hui,hui,alpha);             }             ENDCG         }     } }

 

CG函数

  sign(x)

    :如果 x 大于 0,返回 1;如果 x 小于 0,返回 01;否则返回 0。

技能CD 效果 shader

 

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Powered By Z-Blog 1.8 Arwen Build 90619 Code detection by Codefense  theme by BokeZhuti

Copyright know blog. Some Rights Reserved.站长(msn):webmaster#webgou.info(#换成@) 粤ICP备09183716号