BillBoard: 面片始终面对着摄像机。 广泛引用,eg:渲染烟雾、云朵、闪光效果。
有两种实现方式:
一般通过Shader实现;
另外是小范围简单使用,C#脚本里Update()中使用transform.LookAt(cameraTarget),会让gameObject跟着Camera改变Rotation,保证normal始终朝向cameraTarget。
public
class
LookAtCamera
:
MonoBehaviour
{
public
Transform
target
;
void
Update
()
{
transform
.
LookAt
(
target
);
}
}
shader实现:
广告牌的本质是构建旋转矩阵,3个基向量: up, normal, right.
通常,我们有normal方向(视角方向)和up方向,但两者往往不是垂直的。但其中之一是固定的。
我们假设法线方向是固定的。
首先根据normal和up计算right: right = up x normal
将right归一化后,根据normal和right再次计算出正交的up: up' = normal x right
v2f vert (appdata v)
{
v2f o;
float3
center =
float3
(0,0,0);
float3
viewer = mul(unity_WorldToObject,
float4
(_WorldSpaceCameraPos, 1)).xyz;
float3
normalDir = normalize(viewer - center);
float3
upDir =
float3
(0,1,0);
float3
rightDir = normalize(cross(upDir, normalDir));
upDir = normalize(cross(normalDir, rightDir));
float3
centerOffs = v.vertex.xyz - center;
float3
localPos = center + rightDir * centerOffs.x + upDir * centerOffs.y + normalDir * centerOffs.z;
o.vertex = UnityObjectToClipPos(
float4
(localPos, 1));
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return
o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
col.rgb *= _Color.rgb;
return
col;
}
这里改变ObjectSpace里的vertex,有顶点动画,要求Tag里禁掉Batching,
DisableBatching设置为True.
Tags {
"Queue"
=
"Transparent"
"IgnoreProjector"
=
"True"
"RenderType"
=
"Transparent"
"DisableBatching"
=
"True"
}
但事实上在实际项目中,禁掉Batching的代价太大,在顶点的Color里记录下相对于模型Center的偏移值,就不妨碍Batching啦。