kumak1’s blog

kumak1のイラストや技術ログ

unity shader 内で3Dオブジェクトがカメラを向いているか判定する

Unity の Monobehavior (C#) では、3D空間(ワールド座標)上の「どの位置にいるか」「どこに近いか」「どの方向を向いているのか」という計算をよく行い、こういった計算用のライブラリ(Quaternion, Vector3 など)も揃っており大変便利です。 ですが、Shader に関してはそこまで手厚くなく(その分ノードエディタがあるが・・)手でイチから計算を記述しなくてはならないことも多く、手が止まりがちです。 なので 汎用的に利用できる かつ ちょっと応用っぽいやつ などを気が向いた時にメモしようと思ったのでした。今回はその第一弾。

inline float ObjectLookAtCameraCoef() {
    float3 objectOrigin = mul(UNITY_MATRIX_MV, float4(0,0,0,1)).xyz;
    float3 objectForward = mul(UNITY_MATRIX_MV, float4(0,0,-1,1)).xyz;
    return saturate(0.5 * dot(normalize(objectForward - objectOrigin), float3(0,0,-1)) + 0.5);
}

上記記述で、shader の適用オブジェクトがカメラを向いているかを 0 ~ 1 の float で返します。

ポイントとしては、ビュー座標上で計算することで、カメラの位置(0, 0, 0)を気にしなくて良い事。 0.5 * dot() + 0.5-1 ~ 1 にふるまう dot()0 ~ 1 に押し上げていること(half lambert とかでもこの計算やりますね)。

0 ~ 1 になってしまえば、あとは pow() step()sigmoid などを通して好きに味付けしてあげれば良いでしょう。

で、これで何ができるかというと、目があったときに目が光る、などの一癖ある演出ができます。あとはアイデアしだい。