URP shader

161 阅读9分钟

语法

主要是常用的shader的语法:

Shader "URP/02UnlitShader"
{
	//材质的属性,为外部导入
	Properties
	{
		_MainTex("MainTex",2D)="White"{}               //外部输入一张图片,默认白色
		_BaseColor("BaseColor",Color) = (1,1,1,1)      //外部输入一个颜色值,默认(1,1,1,1)
	}
	//一个子着色器
	SubShader
	{
		//设置渲染管线,和渲染方式
		Tags
		{
			"RenderPipeline" = "UniversalRenderPipeline"          //指定渲染的管线
			"RenderType" = "Opaque"                               //指定渲染的方式
		}
		HLSLINCLUDE
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"   
		CBUFFER_START(UnityPerMaterial)            //常量缓冲区的起点
		float4 _MainTex_ST;            //纹理的缩放和平移,是_MainTex纹理的
		half4 _BaseColor;               //_BaseColor的颜色信息
		CBUFFER_END                  //关闭常量缓冲区
		TEXTURE2D(_MainTex);          //主纹理对象
		SAMPLER(sampler_MainTex);     //采样器
		//a2v中的每一个数据的语义都是有意义的,单v2f中只有SV_POSITION是有意义的
		struct a2v
		{
			float4 positionOS:POSITION;    //语义标记
			float4 normalOS:NORMAL;
			float2 texcoord:TEXCOORD;
		};
		struct v2f
		{
			float4 positionCS:SV_POSITION;
			float2 texcoord:TEXCOORD;
		};
		ENDHLSL              //结束HLSL的代码编写

		pass
		{
			HLSLPROGRAM                   //着色器开始
			#pragma vertex VERT
			#pragma fragment FRAG
			v2f VERT(a2v i)
			{
				v2f o;
				o.positionCS = TransformObjectToHClip(i.positionOS.xyz);   // TransformObjectToHClip 输入为3个维度,输出为4个维度
				o.texcoord = TRANSFORM_TEX(i.texcoord, _MainTex);         //纹理可能会出现平移,缩放等,为了获得更加准确的纹理
				return o;
			}
			half4 FRAG(v2f i) :SV_TARGET
			{
				half4 tex = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.texcoord) * _BaseColor;   //对于纹理进行采样,输入的是纹理,采样器,坐标信息
				//return float4(1, 0, 0, 1);
				return tex;
			}
			ENDHLSL
		}
	}
	//fallback "Hidden/Core/FallbackError"
}

Lambert模型

Shader "URP/03LambertShader"
{
	Properties
	{
		_MainTex("MainTex",2D)="White"{}
		_BaseColor("BaseColor",Color) = (1,1,1,1)
	}
	SubShader
	{
		Tags
		{
			"RenderPipeline" = "UniversalRenderPipeline"
			"RenderType" = "Opaque"
		}
		HLSLINCLUDE
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
		CBUFFER_START(UnityPerMaterial)
		float4 _MainTex_ST;
		half4 _BaseColor;
		CBUFFER_END
		TEXTURE2D(_MainTex);
		SAMPLER(sampler_MainTex);
		struct a2v
		{
			float4 positionOS:POSITION;
			float4 normalOS:NORMAL;
			float4 texcoord:TEXCOORD;
		};
		struct v2f
		{
			float4 positionCS:SV_POSITION;
			float2 texcoord:TEXCOORD;
			float3 normalWS:TEXCOORD1;
		};
		ENDHLSL

		pass
		{
			Tags
			{
				"LightMode"="UniversalForward"   //前向渲染模式
			}
			HLSLPROGRAM
			#pragma vertex VERT
			#pragma fragment FRAG
			v2f VERT(a2v i)
			{
				v2f o;
				o.positionCS = TransformObjectToHClip(i.positionOS.xyz);
				o.texcoord = TRANSFORM_TEX(i.texcoord, _MainTex);
				o.normalWS = TransformObjectToWorldNormal(i.normalOS.xyz, true);   //法线转化到世界空间之中,并且进行归一化
				return o;
			}
			real4 FRAG(v2f i) :SV_TARGET
			{
				half4 tex = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.texcoord) * _BaseColor;
				Light mylight = GetMainLight();                 //获得主光源
				real4 LightColor = real4(mylight.color, 1);     //获得主光源的颜色
				float3 LightDir = normalize(mylight.direction);  //归一化光源的方向,指向光源的
				float LightAten = dot(LightDir, i.normalWS);     //计算cos值
				return tex * LightAten * LightColor;               //计算颜色值
				// return tex*LightAten*LightColor*0.5+0.5;    //半lambert光照
			}
			ENDHLSL
		}
	}
	//fallback "Hidden/Core/FallbackError"
}

blinn-phong-lambert模型

Shader "URP/04BlinnPhongLambertShader"
{
	Properties
	{
		_MainTex("Texture",2D)="while"{}
		_BaseColor("Color",Color)=(1,1,1,1)
		_SpecularRange("SpecularRange",Range(10,300))=10  //pow值,指数
		_SpecularColor("SpecularColor",Color)=(1,1,1,1)   //基础颜色
	}
	SubShader
	{
		Tags
		{
			"RenderType"="Opaque"
			"RenderPipeline"="UniversalRenderPipeline"
		}
		HLSLINCLUDE
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
		CBUFFER_START(UnityPerMaterial)
		float4 _MainTex_ST;
		real4 _BaseColor;
		float _SpecularRange;
		float _SpecularColor;
		CBUFFER_END
		TEXTURE2D(_MainTex);
		SAMPLER(sampler_MainTex);
		struct a2v
		{
			float4 positionOS:POSITION;
			float3 normalOS:NORMAL;
			float2 texcoord:TEXCOORD0;
		};
		struct v2f
		{
			float4 positionCS:SV_POSITION;
			float3 normalWS:NORMAL;
			float3 viewDirWS:TEXCOORD0;
			float2 texcoord:TEXCOORD1;
		};
		ENDHLSL

		pass
		{
			NAME"MainPass"
			Tags
			{
				"LightMode"="UniversalForward"
			}
			HLSLPROGRAM
			#pragma vertex VERT
			#pragma fragment FRAG
			v2f VERT(a2v i)
			{
				v2f o;
				o.positionCS = TransformObjectToHClip(i.positionOS.xyz);
				o.normalWS = TransformObjectToWorldNormal(i.normalOS,true);
				o.viewDirWS = normalize(_WorldSpaceCameraPos.xyz-TransformObjectToWorld(i.positionOS.xyz));  //指向相机的位置 时间空间下光源的位置减去时间空间下着色点的位置
				o.texcoord = TRANSFORM_TEX(i.texcoord,_MainTex);
				return o;
			}
			real4 FRAG(v2f i):SV_TARGET
			{
				Light mylight = GetMainLight();
				float3 LightDirWS = normalize(mylight.direction);
				float spe = dot(normalize(LightDirWS+i.viewDirWS),i.normalWS);   //高光反射项目
				real4 specolor = pow(abs(spe),_SpecularRange)*_SpecularColor;    //高光反射的颜色
				real4 texcolor = (dot(i.normalWS,LightDirWS)*0.5+0.5)*SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.texcoord)*_BaseColor;   //lambert颜色值
				texcolor*=real4(mylight.color,1);
				return specolor+texcolor;
			}
			ENDHLSL
		}
	}
}

法线贴图

Shader "URP/05NormalMapShader"
{
	Properties
	{
		_MainTex("MainTex",2D)="white"{}                            //主纹理
		_BaseColor("BaseColor",Color)=(1,1,1,1)                     //基础颜色
		[Normal]_NormalTex("Normal",2D)="bump"{}                    //法线贴图
		_NormalScale("NormalScale",Range(0,1))=1                    //法线贴图的控制,控制弯曲的程度
		_SpecularRange("SpecularRange",Range(1,200))=50             //高光反射系数
		[HDR]_SpecularColor("SpecularColor",Color)=(1,1,1,1)        //高光反射的颜色
	}
	SubShader
	{
		Tags
		{
			"RenderPipeline"="UniversalRenderPipeline"
		}
		HLSLINCLUDE
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
		CBUFFER_START(UnityPerMaterial)
		float4 _NormalTex_ST;         //法线贴图的控制
		float4 _MainTex_ST;           //主纹理贴图的控制
		real4 _BaseColor;             //主颜色
		real _NormalScale;            //纹理弯曲度
		real _SpecularRange;          //高光的指数值
		real4 _SpecularColor;         //高光颜色
		CBUFFER_END
		TEXTURE2D(_MainTex);
		TEXTURE2D(_NormalTex);
		SAMPLER(sampler_MainTex);
		SAMPLER(sampler_NormalTex);
		struct a2v
		{
			float3 positionOS:POSITION;    //获得模型空间中的位置坐标
			float2 texcoord:TEXCOORD0;     //获得第一道纹理坐标
			float3 normalOS:NORMAL;        //获得法线坐标
			float4 tangentOS:TANGENT;      //获得切线坐标
		};
		struct v2f
		{
			float4 positionCS:SV_POSITION;     //获得切线空间下的坐标
			float4 texcoord:TEXCOORD0;         //纹理坐标,二张图片的纹理的都放在这里
			float4 tangentWS:TANGENT;          //切线坐标
			float4 normalWS:NORMAL;            //法线坐标
			float4 BtangentWS:TEXCOORD1;       //副切线
		};
		ENDHLSL

		pass
		{
			NAME"MainPass"
			Tags
			{
				"LightMode"="UniversalForward"
			}
			HLSLPROGRAM
			#pragma vertex VERT
			#pragma fragment FRAG
			v2f VERT(a2v i)
			{
				v2f o;
				o.texcoord.xy=TRANSFORM_TEX(i.texcoord,_MainTex);   
				o.texcoord.zw=TRANSFORM_TEX(i.texcoord,_NormalTex);
				o.positionCS=TransformObjectToHClip(i.positionOS);          //进行MVP变换
				o.normalWS.xyz=normalize( TransformObjectToWorldNormal(i.normalOS));    //法线进行M变换
				o.tangentWS.xyz=normalize(TransformObjectToWorldDir(i.tangentOS.xyz));   //切线进行M变换
				o.BtangentWS.xyz=cross(o.normalWS.xyz,o.tangentWS.xyz)*i.tangentOS.w*unity_WorldTransformParams.w;   //副切线进行变换
				float3 positionWS=TransformObjectToWorld(i.positionOS);    //顶点坐标进行M变换
				o.tangentWS.w=positionWS.x;
				o.BtangentWS.w=positionWS.y;
				o.normalWS.w=positionWS.z;         //世界空间下的顶点的坐标
				return o;
			}

			real4 FRAG(v2f i):SV_TARGET
			{
				float3 WSpos=float3(i.tangentWS.w,i.BtangentWS.w,i.normalWS.w);
				float3x3 T2W={i.tangentWS.xyz,i.BtangentWS.xyz,i.normalWS.xyz};     //TBN矩阵
				real4 nortex=SAMPLE_TEXTURE2D(_NormalTex,sampler_NormalTex,i.texcoord.zw);   //法线采样
				float3 normalTS=UnpackNormalScale(nortex,_NormalScale);     //法线偏移
				normalTS.z=pow((1-pow(normalTS.x,2)-pow(normalTS.y,2)),0.5);//规范化法线
				float3 norWS=mul(normalTS,T2W);                  //注意这里是右乘T2W的,等同于左乘T2W的逆,变换到世界空间下
				Light mylight=GetMainLight();
				float halflambot=dot(norWS,normalize(mylight.direction))*0.5+0.5;//计算半兰伯特
				real4 diff=SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.texcoord.xy)*halflambot*_BaseColor*real4(mylight.color,1);
				float spe= dot(normalize(normalize(mylight.direction)+normalize(_WorldSpaceCameraPos-WSpos)),norWS);//计算高光
				spe=pow(abs(spe),_SpecularRange);
				return spe*_SpecularColor+diff; 
			}
			ENDHLSL
		}
	}
}

渐变纹理

//渐变纹理
Shader "URP/06BampTexShader"
{
	Properties
	{
		_MainTex("Ramp",2D)="white"{}
		_BaseColor("BaseColor",Color)=(1,1,1,1)
	}
	SubShader
	{
		Tags
		{
			"RenderPipeline"="UniversalRenderPipeline"
			"RenderType"="Opaque"
		}
		HLSLINCLUDE
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
		CBUFFER_START(UnityPerMaterial)
		float4 _MainTex_ST;
		half4 _BaseColor;
		CBUFFER_END
		sampler2D _MainTex;
		struct a2v
		{
			float4 positionOS:POSITION;
			float3 normalOS:NORMAL;
		};
		struct v2f
		{
			float4 positionCS:SV_POSITION;
			float3 normalWS:NORMAL;
		};
		ENDHLSL

		Pass
		{
			Tags
			{
				"LightMode"="UniversalForward"
			}
			HLSLPROGRAM
			#pragma vertex VERT
			#pragma fragment FRAG
			v2f VERT(a2v i)
			{
				v2f o;
				o.positionCS = TransformObjectToHClip(i.positionOS.xyz);
				o.normalWS = normalize(TransformObjectToWorldNormal(i.normalOS));
				return o;
			}
			half4 FRAG(v2f i):SV_TARGET
			{
				real3 lightdir = normalize(GetMainLight().direction);
				float dott = dot(i.normalWS,lightdir)*0.5+0.5;
				half4 tex = tex2D(_MainTex,float2(dott,0.5))*_BaseColor;
				return tex;
			}
			ENDHLSL

		}
	}
}

透明度

Shader "URP/07AlphaBlendShader"
{
	Properties
	{
		_MainTex("MainTex",2D)="white"{}
		_BaseColor("BaseColor",Color)=(1,1,1,1)
		_AlphaTex("AlphaTex",2D)="white"{}
	}
	SubShader
	{
		Tags
		{
			"RenderPipeline"="UniversalRenderPipeline"
			"lgnoreProjector"="True"
			"RenderType"="Transparent"
			"Queue"="Transparent"
		}
		HLSLINCLUDE
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		CBUFFER_START(UnityPerMaterial)
		float4 _MainTex_ST;
		half4 _BaseColor;
		float4 _AlphaTex_ST;
		CBUFFER_END
		TEXTURE2D(_MainTex);
		SAMPLER(sampler_MainTex);
		TEXTURE2D(_AlphaTex);
		SAMPLER(sampler_AlphaTex);
		struct a2v
		{
			float4 positionOS:POSITION;
			float4 normalOS:NORMAL;
			float2 texcoord:TEXCOORD;
		};
		struct v2f
		{
			float4 positionCS:SV_POSITION;
			float4 texcoord:TEXCOORD;
		};
		ENDHLSL

		pass
		{
			Tags
			{
				"LightMode"="UniversalForward"
			}
			Blend SrcAlpha OneMinusSrcColor
			ZWrite Off
			HLSLPROGRAM
			#pragma vertex VERT
			#pragma fragment FRAG
			v2f VERT(a2v i)
			{
				v2f o;
				o.positionCS = TransformObjectToHClip(i.positionOS.xyz);
				o.texcoord.xy = TRANSFORM_TEX(i.texcoord,_MainTex);
				o.texcoord.zw = TRANSFORM_TEX(i.texcoord,_AlphaTex);
				return o;
			}
			real4 FRAG(v2f i):SV_TARGET
			{
				half4 tex = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.texcoord.xy)*_BaseColor;
				float alpha = SAMPLE_TEXTURE2D(_AlphaTex,sampler_AlphaTex,i.texcoord.zw).x;
				return real4(tex.xyz,alpha);
			}
			ENDHLSL
		}
	}

}

复数光源

Shader "URP/08Multi_LightsShader"
{
	Properties
	{
		_MainTex("MainTex",2D)="white"{}
		_BaseColor("BaseColor",Color)=(1,1,1,1)
		[KeywordEnum(ON,OFF)]_ADD_LIGHT("AddLight",float)=1
	}
	SubShader
	{
		Tags{
			"RenderPipeline"="UniversalRenderPipeline"
			"RenderType"="Opaque"
			}
		HLSLINCLUDE
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
		CBUFFER_START(UnityPerMaterial)
		float4 _MainTex_ST;
		half4 _BaseColor;
		CBUFFER_END
		TEXTURE2D(_MainTex);
		SAMPLER(sampler_MainTex);
		struct a2v
		{
			float4 positionOS:POSITION;
			float4 normalOS:NORMAL;
			float2 texcoord:TEXCOORD;
		};
		struct v2f
		{
			float4 positionCS:SV_POSITION;     //剪裁空间下的纹理的坐标
			float2 texcoord:TEXCOORD;
			float3 WS_N:NORMAL;             //世界空间下的法线坐标
			float3 WS_V:TEXCOORD1;          //世界空间下的V向量,当前的坐标指向相机
			float3 WS_P:TEXCOORD2;          //世界空间下的标准坐标
		};
		ENDHLSL

		pass
		{
			Tags{
				"LightMode"="UniversalForward"
				}
			HLSLPROGRAM
			#pragma vertex VERT
			#pragma fragment FRAG
			#pragma shader_feature _ADD_LIGHT_ON _ADD_LIGHT_OFF
			v2f VERT(a2v i)
			{
				v2f o;
				o.positionCS=TransformObjectToHClip(i.positionOS.xyz);
				o.texcoord=TRANSFORM_TEX(i.texcoord,_MainTex);
				o.WS_N=normalize(TransformObjectToWorldNormal(i.normalOS.xyz));
				o.WS_V=normalize(_WorldSpaceCameraPos-TransformObjectToWorld(i.positionOS.xyz));
				o.WS_P=TransformObjectToWorld(i.positionOS.xyz);
				return o;
			}
			real4 FRAG(v2f i):SV_TARGET
			{
				half4 tex=SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.texcoord)*_BaseColor;
				Light mylight=GetMainLight();
				float3 WS_Light=normalize(mylight.direction);
				float3 WS_Normal=i.WS_N;
				float3 WS_View=i.WS_V;
				float3 WS_H=normalize(WS_View+WS_Light);
				float3 WS_Pos=i.WS_P;
				float4 maincolor=(dot(WS_Light,WS_Normal)*0.5+0.5)*tex*float4(mylight.color,1);

				//calcute addlight
				real4 addcolor=real4(0,0,0,1);
				#if _ADD_LIGHT_ON
				int addLightsCount = GetAdditionalLightsCount(); //定义在lighting库函数的方法?返回一个额外灯光的数量
				for(int i=0;i<addLightsCount;i++)
				{
					Light addlight=GetAdditionalLight(i,WS_Pos);//定义在lightling库里的方法?返回一个灯光类型的数据
					float3 WS_addLightDir=normalize(addlight.direction);
					addcolor+=(dot(WS_Normal,WS_addLightDir)*0.5+0.5)*real4(addlight.color,1)*tex*addlight.distanceAttenuation*addlight.shadowAttenuation;
				}
				#else
					addcolor=real4(0,0,0,1);
				#endif
					return maincolor+addcolor;
			}
			ENDHLSL
		}
	}
}


主光源阴影

Shader "URP/09MainLightShadow"
{
	Properties
	{
		_MainTex("MainTex",2D)="white"{}
		_BaseColor("BaseColor",Color)=(1,1,1,1)
		_Gloss("gloss",Range(10,300))=20
		_SpecularColor("SpecularColor",Color)=(1,1,1,1)
	}
	SubShader
	{
		Tags
		{
			"RenderPipeline"="UniversalRenderPipeline"
			"RenderType"="Opaque"
		}
		HLSLINCLUDE
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
		CBUFFER_START(UnityPerMaterial)
		float4 _MainTex_ST;
		half4 _BaseColor;
		half _Gloss;
		real4 _SpecularColor;
		CBUFFER_END
		TEXTURE2D(_MainTex);
		SAMPLER(sampler_MainTex);
		struct a2v
		{
			float4 positionOS:POSITION;
			float4 normalOS:NORMAL;
			float2 texcoord:TEXCOORD;
		};
		struct v2f
		{
			float4 positionCS:SV_POSITION;
			float2 texcoord:TEXCOORD;
			float3 positionWS:TEXCOORD1;
			float3 normalWS:NORMAL;
		};
		ENDHLSL

		pass
		{
			Tags
			{
				"LightMode"="UniversalForward"
			}
			HLSLPROGRAM
			#pragma vertex VERT
			#pragma fragment FRAG
			#pragma multi_compile__MAIN_LIGHT_SHADOWS                //启用主光源的阴影相关
			#pragma multi_compile__MAIN_LIGHT_SHADOWS_CASCADE        //启用主光源级联阴影相关
			#pragma multi_compile__SHADOWS_SOFT                      //启用软阴影相关
			v2f VERT(a2v i)
			{
				v2f o;
				o.positionCS = TransformObjectToHClip(i.positionOS.xyz);
				o.texcoord = TRANSFORM_TEX(i.texcoord,_MainTex);
				o.positionWS = TransformObjectToWorld(i.positionOS.xyz);
				o.normalWS = TransformObjectToWorldNormal(i.normalOS.xyz);
				return o;
			}
			half4 FRAG(v2f i):SV_TARGET
			{
				half4 tex = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.texcoord)*_BaseColor;
				Light mylight = GetMainLight(TransformWorldToShadowCoord(i.positionWS));
				float3 WS_L = normalize(mylight.direction);
				float3 WS_N = normalize(i.normalWS);
				float3 WS_V = normalize(_WorldSpaceCameraPos-i.positionWS);
				float3 WS_H = normalize(WS_V+WS_L);
				tex *= (dot(WS_L,WS_N)*0.5+0.5)*mylight.shadowAttenuation*real4(mylight.color,1);   //lambert模型光源衰减
				float4 Specular = pow(max(dot(WS_N,WS_H),0),_Gloss)*_SpecularColor*mylight.shadowAttenuation;   //高光衰减
				return tex+Specular;
			}
			ENDHLSL
		}
		UsePass "Universal Render Pipeline/Lit/ShadowCaster"        //使用urp管线渲染阴影
	}
}

序列帧算法

Shader "URP/12SequenceFramesShader"
{
	Properties
	{
		_MainTex("MainTex",2D)="white"{}
		_BaseColor("BaseColor",Color)=(1,1,1,1)
		_Sheet("Sheet",Vector)=(1,1,1,1)
		_FrameRate("FrameRate",float)=25
	}
	SubShader
	{
		Tags
		{
			"RenderPipeline"="UniversalRenderPipeline"
			"Queue"="Transparent"
			"RenderType"="Transparent"
		}
		HLSLINCLUDE
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		CBUFFER_START(UnityPerMaterial)
		float4 _MainTex_ST;
		half4 _BaseColor;
		half4 _Sheet;
		float _FrameRate;
		CBUFFER_END
		TEXTURE2D(_MainTex);
		SAMPLER(sampler_MainTex);
		struct a2v
		{
			float4 positionOS:POSITION;
			float4 normalOS:NORMAL;
			float2 texcoord:TEXCOORD;
		};
		struct v2f
		{
			float4 positionCS:SV_POSITION;
			float2 texcoord:TEXCOORD;
		};
		ENDHLSL

		pass
		{
			Tags
			{
				"LightMode"="UniversalForward"
			}
			ZWrite off
			Blend SrcAlpha OneMinusSrcAlpha
			HLSLPROGRAM
			#pragma vertex VERT
			#pragma fragment FRAG
			v2f VERT(a2v i)
			{
				v2f o;
				o.positionCS = TransformObjectToHClip(i.positionOS.xyz);
				o.texcoord = TRANSFORM_TEX(i.texcoord,_MainTex);
				return o;
			}
			half4 FRAG(v2f i):SV_TARGET
			{
				float2 uv;
				uv.x = i.texcoord.x/_Sheet.x+frac(floor(_Time.y*_FrameRate)/_Sheet.x);
				uv.y = i.texcoord.y/_Sheet.y+1-frac(floor(_Time.y*_FrameRate/_Sheet.x)/_Sheet.y);
				return SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,uv);
			}
			ENDHLSL
		}
	}
}

广告牌算法

Shader "URP/13BillboardAgorithmShader"
{
	Properties
	{
		_MainTex("MainTex",2D)="white"{}
		_BaseColor("BaseColor",Color)=(1,1,1,1)
		_Sheet("Sheet",Vector)=(1,1,1,1)
		_FrameRate("FrameRate",float)=25
		[KeywordEnum(LOCK_Z,FREE_Z)]_Z_STAGE("Z_Stage",float)=1
	}
	SubShader
	{
		Tags
		{
			"RenderPipeline"="UniversalRenderPipeline"
			"Queue"="Transparent"
			"RenderType"="Transparent"
		}
		HLSLINCLUDE
		#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
		CBUFFER_START(UnityPerMaterial)
		float4 _MainTex_ST;
		half4 _BaseColor;
		half4 _Sheet;
		float _FrameRate;
		CBUFFER_END
		TEXTURE2D(_MainTex);
		SAMPLER(sampler_MainTex);
		struct a2v
		{	
			float4 positionOS:POSITION;
			float4 normalOS:NORMAL;
			float2 texcoord:TEXCOORD;
		};
		struct v2f
		{
			float4 positionCS:SV_POSITION;
			float2 texcoord:TEXCOORD;
		};
		ENDHLSL

		pass
		{
			Tags
			{
				"LightMode"="UniversalForward"
			}
			ZWrite off
			Blend SrcAlpha OneMinusSrcAlpha
			HLSLPROGRAM
			#pragma vertex VERT
			#pragma fragment FRAG
			#pragma shader_feature_local _Z_STAGE_LOCK_Z
			v2f VERT(a2v i)
			{
				v2f o;
				float3 newZ = TransformWorldToObject(_WorldSpaceCameraPos);
				#ifdef _Z_STAGE_LOCK_Z
				newZ.y = 0;
				#endif
				newZ.y = 0;
				newZ = normalize(newZ);
				float3 newX = abs(newZ.y)<0.99?cross(float3(0,1,0),newZ):cross(newZ,float3(0,0,1));
				newX = normalize(newX);
				float3 newY = cross(newZ,newX);
				float3x3 Matrix = {newX,newY,newY};
				float3 newpos = mul(i.positionOS.xyz,Matrix);  //右乘
				o.positionCS = TransformObjectToHClip(newpos);
				o.texcoord = TRANSFORM_TEX(i.texcoord,_MainTex);
				return o;
			}
			half4 FRAG(v2f i):SV_TARGET
			{
				float2 uv;
				uv.x = i.texcoord.x/_Sheet.x+frac(floor(_Time.y*_FrameRate)/_Sheet.x);
				uv.y = i.texcoord.y/_Sheet.y+1-frac(floor(_Time.y*_FrameRate/_Sheet.x)/_Sheet.y);
				return SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,uv);
			}
			ENDHLSL
		}
	}
}