(一)先看效果图:由于我用的sin函数,所以 冲击波扩散出去 还会收缩回来(请忽略收缩回来的效果)
1.先修改设置:
(1)由于使用URP,不支持GrabPass,所以直接修改配置,使用_CameraOpaqueTexture来代替。
(2)基本原理:
对屏幕坐标进行扰动:
第一:只对圆环上的坐标扰动(白色部分),黑色部分不做变动。
第二:圆环从内向外扩展运动。
第三: 最主要的就是 step函数,形成圆圈 -》 形成圆环。
Shader "Unlit/Ring"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Radius("Radius",Range(0,1)) = 0.5
_RingWidth("RingWidth",Range(0,0.5)) = 0.1
_Color("Color",color) = (0,1,0,1)
_Distort("Distort",Range(1,100)) = 1
}
SubShader
{
Tags { "Queue"="Transparent" "RenderType"="Transparent" }
LOD 100
// --- 在SRP中不支持 GrabPass,用 _CameraOpaqueTexture 来取代
// 在 project setting -> Quality - >
// GrabPass{
// "_GrabTexture"
// }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 screenPos : TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Radius,_RingWidth;
sampler2D _CameraOpaqueTexture;
float4 _CameraOpaqueTexture_TexelSize;
float4 _Color;
float _Distort;
float ring(float2 uv,float2 cricleCenter,float radius,float ringWidth){
float dis = distance(uv,cricleCenter);
float mask = step(dis,radius + ringWidth) * step(radius-ringWidth,dis);
float data = 1 - abs(dis - radius)/ringWidth;
//return data;
return mask * data;
}
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.screenPos = ComputeScreenPos(o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float circle = ring(i.uv,float2(0.5,0.5),_Radius * sin(_Time.y),_RingWidth);
float2 scrUV = i.screenPos.xy / i.screenPos.w;
float4 endCol = tex2D(_CameraOpaqueTexture,scrUV + circle * _CameraOpaqueTexture_TexelSize.xy * _Distort);
return endCol;// * _Color;
}
ENDCG
}
}
}