最终目标:
实现方式是定义一个随时间变换的扩散半径,但是扩散的半径必须在0到最大扩散半径之间不断的循环,首先想到的是用sin与cos函数,但是用这两个处理的话,扩散的速率不是均匀变换的,我们需要自己定义一个函数:
X轴对应的时间,Y轴是当前扩散半径;这个函数在下面的LinearTransform里面定义;
Shader "Custom/ReplaceColor" { Properties { _Color ("Main Color",Color) = (1,1,1,1) _ReplaceColor("Replace Color",Color) = (1,1,1,1) _Speed("Speed",Range(0.0,1.0)) = 0.5 //扩散的速率 _MaxRadium("MaxRadium",Range(0.1,1)) = 0.7 //扩散的最大半径 } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" float _Speed; fixed4 _Color; fixed4 _ReplaceColor; float _MaxRadium; struct a2v { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(a2v i) { v2f o; o.pos = UnityObjectToClipPos(i.vertex); o.uv = i.texcoord; return o; } //定义一个匀速变换的函数 float2 LinearTransform(float time) { float value = floor(time); float lerpValue = value % 2 > 0 ? 1 : 0; float retValue = time - value ; return float2(retValue,lerpValue); } fixed4 frag(v2f i) : SV_Target { float2 dir = i.uv - float2(0.5,0.5);//当前像素点相对中心点的位置 float rad = length(dir); float2 value = LinearTransform(_Speed * _Time.y); float currentRad = value.x * _MaxRadium;//当前扩散的半径 fixed4 tempColor = lerp(_Color,_ReplaceColor, value.y); fixed4 tempReplaceColor = lerp(_ReplaceColor,_Color, value.y); float shouldReplace = step(rad,currentRad);//判断当前像素是否需要替换颜色 fixed4 color = lerp(tempColor,tempReplaceColor,shouldReplace); return color; } ENDCG } } }