2つのカメラで特定のものを前面に描画する

通常はカメラは1つでゲームを作ることができます。Unityで新しいシーンを作れば、Main Cameraが作られていてこれをそのまま使うだけで物体の表示が可能です。

複数のカメラを使うと単体のカメラではできない表現が可能になります。例えば一部のオブジェクトを常に前面に表示したり、画面を上下で分けた2P対戦といったことが可能です。
これはCameraコンポーネントのプロパティのうち、Clear Flags、Culling Mask、Viewport Rect、Depthをいじることで実現できます。 (画面の分割についてはViewport Rectを適切に設定したカメラを複数用意しておくだけで実現が可能なのでここでは詳しく取り上げません。)

一部のオブジェクトが常に前面に表示するということを今回は試してみたいと思います。 といってもよくわからないのでまずは結果を示します。
 

左の方は最終的に得られた結果です。右の方は1つのカメラ(通常の表示ということです。)でユニティちゃんを表示したものです。
前者は眉毛が髪に隠れないで表示されています。(アニメ的な表現らしいです。目が見えると印象がはっきりしていますね。)
目と眉毛が他のモデルよりも後に描かれることでこのように前面に表示することができます。とくにプログラムで制御せずに設定を変えることでこのような表示が可能です。

説明

ヒエラルキーの構成は以下の通りです。unitychanはユニティちゃんモデルのプレハブを置いただけで、Directional Lightも単なる光源です。Main CameraとSubCameraがあるのがポイントでSubCameraが前面に表示するオブジェクトだけを描画するカメラです。Main Cameraがすべてのオブジェクトを描画した後で、SubCameraが特定のオブジェクトを上書きすることでそのようになります。

Main CameraとSubCameraの設定は以下の通りです。
 

Main CameraとSubCameraは同じ位置にいるように設定し、Main CameraとSubCameraのCameraの設定は基本的に同じです。これは同じもの対象として描画しているためです。
Main CameraではClear FlagsがSkyboxであり、Skyboxで以前の結果をリセットしています。これはMain CameraのDepth(カメラ同士の描画の順番のこと。Depthという名前はややこしい。)が-1であり、SubCameraよりも先に描かれるためバッファクリアの処理を指定しています。描画物の制限も特に行わず全てのものが描画されます。(最初に示した通常の絵が描かれているということ)
SubCameraはMain Cameraの後に描画したいため、Depthの値が0で大きくしてあります。SubCameraはMain Cameraの描画結果を消してしまわないようClear FlagsにはDepth onlyが指定されています。これによりデプス(深度、Zとも)だけがクリアされ、SubCameraの描画結果は上書きされます。特定のゲームオブジェクトを描画するためにCulling Maskが設定されています。Subというのはレイヤーの名前です。

ユニティちゃんモデルを構成するゲームオブジェクトのうち目と眉毛のもののレイヤーをSubにすれば、それだけがSubCameraでも描画されることになるということです。
SubCameraの描画しているものはこんな感じです。

unitychanはモデルなので、複数の階層で構成されています。以下で選択されているものが目と眉毛の表示に関係するレンダラーをもつゲームオブジェクトなので、それらのレイヤーをSubにします。

以上の設定すると最初に載せた絵が作れます。

この方法はお手軽ですが、欠点もあります。言わなければ気付かないかなーと思いましたが、モデルを動かしたりするとすぐにバレるので言っておきます。
SubCameraにとっては目と眉毛のオブジェクトしか見えないため、顔のモデル(頬とか鼻とか)に隠れて欲しい左目が表示されてしまいます。またモデルの作りによりますが、前面に表示したためにユニティちゃんの目がおかしくなります。
この解決はかなり大変です。モデル自体がメッシュの前後関係を変えても破綻しにくい作りになっていること、描画する物体がカメラにとって表側に向いているかの判定をカスタマイズするといった対応が要ると思います。

最後にユニティちゃんを回転させた動画を載せておきます。モーションさせたり、動かしたりするといろいろ問題が出てきます。(左の方の滲みは画像の都合なので無視してください。)

今回はモデルを使って見た目を変えてみましたが、ゲームでは重要なものを目立たせるといった使われ方があるでしょう。

© Unity Technologies Japan/UCL

コメント

  1. より:

    前面に表示したい場合はこの方法よりステンシルバッファを使った方がいいんですか?

  2. 管理人 より:

    パフォーマンスが問題なければ、自前のシェーダーでステンシルバッファを使う方が良いと思います。
    前面に置きたいものとそれよりも後ろに置かれるものにステンシルバッファを参照するようなシェーダーをセットする必要があると思います。特別なシェーダーを数多くのものに適用するとパフォーマンスを悪化させやすいです。