一、内置渲染管线Shader
Shader"Custom/ImageRoll"
{
Properties
{
_MainTex ("Main Tex", 2D) = "white" {}
_Width ("Width", float) = 0.5
_Distance ("Distance", float) = 0
}
SubShader
{
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
Pass
{
Tags { "LightMode"="ForwardBase" }
ZTest off
ZWrite Off
Blend SrcAlpha
OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float _Width;
float _Distance;
struct a2v
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.x = v.texcoord.x;
o.uv.y = v.texcoord.y;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
i.uv.x = frac(i.uv.x * _Width + _Distance);
fixed4 c = tex2D(_MainTex, i.uv);
return c;
}
ENDCG
}
}
FallBack"Transparent/VertexLit"
}
二、URP渲染管线Shader
Shader "Custom/ImageRollURP"{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_Distance("Distance", Float) = 0
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent" }
LOD 100
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_local _ DISTANCE_ON
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 position : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 position : SV_POSITION;
float2 uv : TEXCOORD0;
};
float _Distance;
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.position = TransformObjectToHClip(IN.position.xyz);
OUT.uv = IN.uv;
return OUT;
}
sampler2D _MainTex;
float4 _MainTex_ST;
half4 frag(Varyings IN) : SV_Target
{
float2 uv = IN.uv;
uv.x = frac(uv.x + _Distance);
half4 c = tex2D(_MainTex, uv);
return c;
}
ENDHLSL
}
}
FallBack "Diffuse"
}
三、代码控制
using UnityEngine;
public class ImageRoll : MonoBehaviour
{
public float speed = 0.1f;
private Material mtl;
float distance;
// Use this for initialization
void Start()
{
mtl = GetComponent<SpriteRenderer>().material;
distance = 0;
}
// Update is called once per frame
void Update()
{
distance += speed * Time.deltaTime;
mtl.SetFloat("_Distance", distance);
}
}
四、效果展示