概要
Unityでオブジェクトのスケールをマイナスにしたらポリゴンが反転しているのが気になったので、
調査したことを共有しようと思います。
経緯
「変換行列でスケールを反転させてもポリゴンは反転しないよね?」って思ったんですが、
実際に確認したところ、Unityでは反転してるみたいなのでちょっと調査してみることにしました。
動作環境
- Windows 10
- Unity 2019.3.14f1
- UE4
検証パターン
左側がスケールをそのまま、右側はZスケールを-1に設定したものです。
Zスケールを 1 -> -1 にアニメーションさせています。
スケールがマイナスになったときに、ポリゴンが反転していますね。
ポリゴンが反転しない場合のイメージ
※あくまでイメージのために作成した画像です。実際にはこうなりません。
右側のモデルはシェーダーでフロントフェイスカリングにしています。
仮説
調査前は以下のように予想してました。
仮説1. ポリゴンを反転させた別モデルを用意して、スケールが負のモデルに使用している
この場合、モデルに対するグラフィックメモリの消費が増えますが、バッチング対象にはなります。
仮説2. フロントフェイスカリングに切り替えている
レンダリング前にGL.invertCulling(true)
をコールしているイメージです。
バッチング対象外になるぐらいがデメリットでしょうか。
調査結果
ドキュメントが見つからなかったのでわかりません!
ですが、1つ気になる動きがありました。
Frame Debuggerで「検証パターン」を確認したところ、以下のようなメッセージが表示されていました。
X, Y, Z スケールのうち奇数個がマイナスの場合は、バッチング対象外になるようですね。
ということで 仮説2 が近いのかなと思いました。
古い資料ですが こちら にも"What breaks batching"の中に"Odd Negative Scaling"とありますね。
結論
詳細は不明だが、UnityはOdd Negative Scalingのオブジェクトの場合、ポリゴンを反転させている。
余談、UE4の場合
じゃあUE4はどうなってるのかな?ってことで調べてみました。
Unreal Editor 4.24.3で確認しました。
Actor(オブジェクト)をOdd Negative Scalingにした場合
親をOdd Negative Scalingにした場合
反転しませんでした。
親のスケールはカリングに影響しない仕様なのかもしれません。
雑感
よくよく考えてみると、スケールが負になったときにポリゴンを反転させた方がいろいろと好都合な気はしました。
ポリゴンを反転させなかったらモデルの見た目がおかしくなるので、反転モデル向けに専用マテリアルが必要になるなど考慮することも多くなりそうですね。
あと、記事を書いていて「ポリゴンの反転」がゲシュタルト崩壊しそうになりました。。。