文章目录
- 前言
- 一、个性化修改面向摄像机效果
- 1、把上一篇文章中求的 Z轴基向量 投影到 XoZ平面上
- 2、其余步骤和之前的一致
- 3、在属性面板定义一个变量,控制面片面向摄像机的类型
- 4、效果
- 二、适配BRP
- 三、最终代码
前言
在上一篇文章中,我们用Shader实现了面片一直面向摄像机的效果。
- Unity中Shader面片一直面向摄像机
在这篇文章中,我们对其进行个性化修改 及 BRP下的适配。
一、个性化修改面向摄像机效果
- 在很多时候,我们并不需要面片在上下方向跟随摄像机旋转
- 我们只需要面片跟随摄像机的左右旋转。
- 那么,我们就需要对上一篇文章中实现的效果进行修改
1、把上一篇文章中求的 Z轴基向量 投影到 XoZ平面上
- 最简单的办法就是,先把摄像机坐标转化到模型本地坐标
- 让 y 值为0后,再归一化
float3 viewDir = mul(GetWorldToObjectMatrix(),float4(_WorldSpaceCameraPos,1)).xyz;
viewDir = float3(viewDir.x,0,viewDir.z);
viewDir = normalize(viewDir);
2、其余步骤和之前的一致
- 假设Y轴基向量
- 求X轴基向量
- 求Y轴基向量
3、在属性面板定义一个变量,控制面片面向摄像机的类型
- 属性面板
[Enum(Billboard,1,VerticalBillboard,0)]_BillboardType(“BillboardType”,int) = 1
- 在顶点着色器
float3 viewDir = mul(GetWorldToObjectMatrix(),float4(_WorldSpaceCameraPos,1)).xyz;
viewDir.y *= _BillboardType;
viewDir = normalize(viewDir);
4、效果
二、适配BRP
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_ENDTEXTURE2D(_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}}
}