在上一篇文章中,我们用Shader实现了面片一直面向摄像机的效果。
在这篇文章中,我们对其进行个性化修改 及 BRP下的适配。
float3 viewDir = mul(GetWorldToObjectMatrix(),float4(_WorldSpaceCameraPos,1)).xyz;
viewDir = float3(viewDir.x,0,viewDir.z);
viewDir = normalize(viewDir);
[Enum(Billboard,1,VerticalBillboard,0)]_BillboardType(“BillboardType”,int) = 1
float3 viewDir = mul(GetWorldToObjectMatrix(),float4(_WorldSpaceCameraPos,1)).xyz;
viewDir.y *= _BillboardType;
viewDir = normalize(viewDir);
SubShader
{
Tags
{
//渲染类型
"RenderType"="Transparent"
//渲染队列
"Queue"="Transparent"
}
Blend [_SrcFactor] [_DstFactor]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float3 vertexOS : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertexCS : SV_POSITION;
float2 uv : TEXCOORD1;
UNITY_FOG_COORDS(2)
};
float4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
half4 _Sequence;
half _BillboardType;
v2f vert(appdata v)
{
v2f o;
//Z轴基向量
float3 viewDir = mul(unity_WorldToObject,float4(_WorldSpaceCameraPos,1)).xyz;
viewDir.y *= _BillboardType;
viewDir = normalize(viewDir);
//假设Y轴基向量
float3 upDir = float3(0,1,0);
//X轴基向量(左手坐标系、逆时针叉乘)
float3 rightDir = normalize(cross(viewDir,upDir));
//Y轴基向量(左手坐标系、逆时针叉乘)
upDir = normalize(cross(rightDir,viewDir));
//顶点应用旋转
//法一:向量乘法
float3 newVertexOS = rightDir * v.vertexOS.x + upDir * v.vertexOS.y + viewDir * v.vertexOS.z;
//法二:矩阵乘法
/*float4x4 M = float4x4
(
rightDir.x,upDir.x,viewDir.x,0,
rightDir.y,upDir.y,viewDir.y,0,
rightDir.z,upDir.z,viewDir.z,0,
0,0,0,1
);
float3 newVertexOS = mul(M,v.vertexOS).xyz;*/
o.vertexCS = UnityObjectToClipPos(newVertexOS);
o.uv = float2(v.uv.x / _Sequence.y, v.uv.y / _Sequence.x + (_Sequence.x - 1) / _Sequence.x);
o.uv.x += frac(floor(_Time.y * _Sequence.y * _Sequence.z) / _Sequence.y);
o.uv.y -= frac(floor(_Time.y * _Sequence.y * _Sequence.z / _Sequence.y) / _Sequence.x);
//o.uv.x += floor(_Time.y);
//o.uv = float2(v.uv.x/4,v.uv.y/4);
//o.uv = TRANSFORM_TEX(v.uv,_MainTex);
UNITY_TRANSFER_FOG(o, o.vertex)
return o;
}
half4 frag(v2f i) : SV_Target
{
float4 mainTex = tex2D(_MainTex, i.uv);
float4 col = mainTex * _Color;
UNITY_APPLY_FOG(i.fogCoord, col)
col.rgb = col.rgb * col.a;
return col;
}
ENDCG
}
}
Shader "MyShader/URP/P3_10_5"
{
Properties
{
[Enum(UnityEngine.Rendering.BlendMode)]_SrcFactor("SrcFactor",int) = 0
[Enum(UnityEngine.Rendering.BlendMode)]_DstFactor("DstFactor",int) = 0
_Color("Color",Color) = (1,1,1,1)
_MainTex("MainTex",2D) = "white"{}
_Sequence("Row(X) Column(Y) Speed(Z)",Vector) = (1,1,1,1)
[Enum(Billboard,1,VerticalBillboard,0)]_BillboardType("BillboardType",int) = 1
}
SubShader
{
Tags
{
//告诉引擎,该Shader只用于 URP 渲染管线
"RenderPipeline"="UniversalPipeline"
//渲染类型
"RenderType"="Transparent"
//渲染队列
"Queue"="Transparent"
}
Blend [_SrcFactor] [_DstFactor]
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attribute
{
float4 vertexOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varying
{
float4 vertexCS : SV_POSITION;
float2 uv : TEXCOORD1;
float fogCoord : TEXCOORD2;
};
CBUFFER_START(UnityPerMaterial)
float4 _Color;
float4 _MainTex_ST;
half4 _Sequence;
half _BillboardType;
CBUFFER_END
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
Varying vert(Attribute v)
{
Varying o;
//Z轴基向量
float3 viewDir = mul(GetWorldToObjectMatrix(),float4(_WorldSpaceCameraPos,1)).xyz;
viewDir.y *= _BillboardType;
viewDir = normalize(viewDir);
//假设Y轴基向量
float3 upDir = float3(0,1,0);
//X轴基向量(左手坐标系、逆时针叉乘)
float3 rightDir = normalize(cross(viewDir,upDir));
//Y轴基向量(左手坐标系、逆时针叉乘)
upDir = normalize(cross(rightDir,viewDir));
//顶点应用旋转
//法一:向量乘法
float3 newVertexOS = rightDir * v.vertexOS.x + upDir * v.vertexOS.y + viewDir * v.vertexOS.z;
//法二:矩阵乘法
/*float4x4 M = float4x4
(
rightDir.x,upDir.x,viewDir.x,0,
rightDir.y,upDir.y,viewDir.y,0,
rightDir.z,upDir.z,viewDir.z,0,
0,0,0,1
);
float3 newVertexOS = mul(M,v.vertexOS).xyz;*/
o.vertexCS = TransformObjectToHClip(newVertexOS);
o.uv = float2(v.uv.x / _Sequence.y, v.uv.y / _Sequence.x + (_Sequence.x - 1) / _Sequence.x);
o.uv.x += frac(floor(_Time.y * _Sequence.y * _Sequence.z) / _Sequence.y);
o.uv.y -= frac(floor(_Time.y * _Sequence.y * _Sequence.z / _Sequence.y) / _Sequence.x);
//o.uv.x += floor(_Time.y);
//o.uv = float2(v.uv.x/4,v.uv.y/4);
//o.uv = TRANSFORM_TEX(v.uv,_MainTex);
o.fogCoord = ComputeFogFactor(o.vertexCS.z);
return o;
}
half4 frag(Varying i) : SV_Target
{
float4 mainTex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
float4 col = mainTex * _Color;
col.rgb = MixFog(col.rgb, i.fogCoord);
col.rgb = col.rgb * col.a;
return col;
}
ENDHLSL
}
}
SubShader
{
Tags
{
//渲染类型
"RenderType"="Transparent"
//渲染队列
"Queue"="Transparent"
}
Blend [_SrcFactor] [_DstFactor]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float3 vertexOS : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertexCS : SV_POSITION;
float2 uv : TEXCOORD1;
UNITY_FOG_COORDS(2)
};
float4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
half4 _Sequence;
half _BillboardType;
v2f vert(appdata v)
{
v2f o;
//Z轴基向量
float3 viewDir = mul(unity_WorldToObject,float4(_WorldSpaceCameraPos,1)).xyz;
viewDir.y *= _BillboardType;
viewDir = normalize(viewDir);
//假设Y轴基向量
float3 upDir = float3(0,1,0);
//X轴基向量(左手坐标系、逆时针叉乘)
float3 rightDir = normalize(cross(viewDir,upDir));
//Y轴基向量(左手坐标系、逆时针叉乘)
upDir = normalize(cross(rightDir,viewDir));
//顶点应用旋转
//法一:向量乘法
float3 newVertexOS = rightDir * v.vertexOS.x + upDir * v.vertexOS.y + viewDir * v.vertexOS.z;
//法二:矩阵乘法
/*float4x4 M = float4x4
(
rightDir.x,upDir.x,viewDir.x,0,
rightDir.y,upDir.y,viewDir.y,0,
rightDir.z,upDir.z,viewDir.z,0,
0,0,0,1
);
float3 newVertexOS = mul(M,v.vertexOS).xyz;*/
o.vertexCS = UnityObjectToClipPos(newVertexOS);
o.uv = float2(v.uv.x / _Sequence.y, v.uv.y / _Sequence.x + (_Sequence.x - 1) / _Sequence.x);
o.uv.x += frac(floor(_Time.y * _Sequence.y * _Sequence.z) / _Sequence.y);
o.uv.y -= frac(floor(_Time.y * _Sequence.y * _Sequence.z / _Sequence.y) / _Sequence.x);
//o.uv.x += floor(_Time.y);
//o.uv = float2(v.uv.x/4,v.uv.y/4);
//o.uv = TRANSFORM_TEX(v.uv,_MainTex);
UNITY_TRANSFER_FOG(o, o.vertex)
return o;
}
half4 frag(v2f i) : SV_Target
{
float4 mainTex = tex2D(_MainTex, i.uv);
float4 col = mainTex * _Color;
UNITY_APPLY_FOG(i.fogCoord, col)
col.rgb = col.rgb * col.a;
return col;
}
ENDCG
}
}
}