通过计算旋转后的三个正交基 来构建旋转矩阵。1.首先要计算视角向量。模型的中点Center可以设置为(0,0,0)。ViewDir = 摄像机的位置 - Center可以得到视角向量。2.向上向量Up (0,1,0)这个最简单。3.构建向右向量可以通过叉积计算出垂直与Up和View的向右向量Right。4.再通过Up和Right向量叉积计算出新的视野View’向量。5.最后通过Up Right View’三个正交基构建出旋转矩阵。
Shader "QShader/Billboard_ByY"{
Properties{
_MainTex("Main Texture",2D) = "white"{}
}
SubShader{
Tags{"Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True" "DisableBatching" = "True"}
//我们在这里关闭Shader的批处理操作。
pass {
Tags{"LightMode" = "Always"}
Cull Off //关闭剔除,让模型的两面都可以显示
CGPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
#include "Lighting.cginc"
#include "UnityCG.cginc"
sampler2D _MainTex;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f Vertex(appdata_base v) {
v2f o;
float3 center = float3(0,0,0);
//把摄像机的位置转换到模型空间
float3 viewer = mul(unity_WorldToObject,float4(_WorldSpaceCameraPos,1)).xyz;
//获取当前的视角向量
float3 viewDir = viewer - center;
//归一化视角向量
viewDir = normalize(viewDir);
//向上向量
float3 upDir = float3(0,1,0);
//向右向量
float3 rightDir = normalize(cross(upDir,viewDir));
//归一化向右向量
viewDir = normalize(cross(upDir,rightDir));
//每个顶点的偏移进行空间转换,然后再将这个偏移还原到新的空间(加上center)
float3 centerOffset = v.vertex.xyz - center;
float3x3 _RotateMatrix = transpose(float3x3(rightDir,upDir,viewDir));
float3 pos = mul(_RotateMatrix,centerOffset) + center;
o.pos = UnityObjectToClipPos(float4(pos,1));
o.uv = v.texcoord;
return o;
}
fixed4 Fragment(v2f i) :SV_TARGET{
return tex2D(_MainTex,i.uv);
}
ENDCG
}
}
}