Shader "Custom/Trail"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
_TrailLength ("Trail Length", Float) = 1.0
_TrailTexture ("Trail Texture", 2D) = "white" {}
}
SubShader
{
Tags {"Queue"="Transparent" "RenderType"="Transparent"}
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag_ps
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float4 color : COLOR;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
float3 worldPos : TEXCOORD1;
float4 trailPos : TEXCOORD2;
};
float4x4 _ObjectToWorld;
float4x4 _WorldToObject;
float4 _Color;
float _TrailLength;
float4 _trailColor;
sampler2D _MainTex;
sampler2D _TrailTexture;
v2f vert (appdata v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.color = v.color _Color;
o.uv = v.uv;
o.worldPos = mul(_ObjectToWorld, v.vertex).xyz; //获取世界坐标
o.trailPos = v.vertex; //将顶点位置传递到片元着色器
return o;
}
fixed4 frag_ps (v2f i) : COLOR //顶点着色器
{
fixed4 col = tex2D(_MainTex, i.uv) i.color; //从主纹理获取颜色值
float trailAlpha = 0.0; //初始化残影的透明度为0
float3 camPos = UnityObjectToClipPos(i.worldPos); //获取摄像机在模型坐标系中的位置
for(int t = 0; t < 4; t++) //循环4次
{
float trailOffset = t 0.23; //计算每次的偏移量
float4 trailPos = mul(_ObjectToWorld, i.trailPos); //将顶点位置转换为世界坐标
float4 camTrailPos = camPos + (normalize(trailPos - _WorldSpaceCameraPos) trailOffset); //根据相机位置计算残影位置
float4 projCamTrailPos = UnityObjectToClipPos(camTrailPos); //将残影位置转换为裁剪空间坐标
float depthValue = (projCamTrailPos.z / projCamTrailPos.w); //将深度值转换为NDC坐标系中的深度值
float distFromCenter = length(projCamTrailPos.xy); //计算残影到屏幕中心的距离
float trailAlpha2 = ((1.0 - depthValue) (1.0 - distFromCenter)) / _TrailLength; //计算残影透明度
if(trailAlpha2 > trailAlpha)
trailAlpha = trailAlpha2; //取透明度最大的值作为该像素的残影透明度
}
col.a = trailAlpha; //将残影透明度应用到颜色的Alpha通道上
col.rgb *= (1.0 - trailAlpha); //在残影的位置上减少颜色的强度
return col;
}
ENDCG
}
}
FallBack "Diffuse"
}
shader实现移动产生残影
于 2023-03-30 14:08:25 首次发布