语法
主要是常用的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
}
}
}