UnityのUniversalRPで開発中のCamera Stacking Systemを試す

# はじめに

現在はUnity2019.3以上のPackage ManagerからCamera Stacking Systemに対応したUniversalRP7.2以上をインストールできます。
また[UniversalRenderingExamples](https://github.com/Unity-Technologies/UniversalRenderingExamples)の[Character UI](https://github.com/Unity-Technologies/UniversalRenderingExamples/wiki/Character-UI)と[3D Skybox](https://github.com/Unity-Technologies/UniversalRenderingExamples/wiki/3D-Skybox)にCamera Stacking Systemを利用したサンプルプロジェクトがあります。

**Character UI**
![Main.gif](https://github.com/Unity-Technologies/UniversalRenderingExamples/wiki/images/3D-Character-UI/Main.gif)
**3D Skybox**
![Main.gif](https://github.com/Unity-Technologies/UniversalRenderingExamples/wiki/images/3D-Skybox/Main.gif)

---

UnityのLWRPはカメラスタックをサポートしないと明言されていました。
流石に不便だったのかUnity2019.2のロードマップにカメラスタックが追加されました。

[Camera Rendering in LWRP](https://docs.google.com/document/d/1GDePoHGMngJ-S0Da0Fi0Ky8jPxYkQD5AkVFnoxlknUY/edit)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">2019.2 でCamera Stacking Systemが実装されるので、LWRPでカメラの結果を重ねるのはそこから可能になる感じですね <a href="https://t.co/4HoWunmCQv">pic.twitter.com/4HoWunmCQv</a></p>&mdash; h.omae (@pigeon6) <a href="https://twitter.com/pigeon6/status/1121268133530984449?ref_src=twsrc%5Etfw">April 25, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

残念ながら2019.2のリリースに間に合わなかったのですが[Universal/2019.3/backports by phi-lira · Pull Request #5462](https://github.com/Unity-Technologies/ScriptableRenderPipeline/pull/5462)で[release/2019.3](https://github.com/Unity-Technologies/ScriptableRenderPipeline/tree/release/2019.3)ブランチにマージされたので試してみます。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Camera Stacking for URP has landed in main code base. This is definitely the longest PR I did in my life (6+ months), but it&#39;s finally here. This is target to be released in 7.2.0 package for URP end of this month. <a href="https://t.co/5Pi19Lzot3">https://t.co/5Pi19Lzot3</a></p>&mdash; Felipe Lira (@phi_lira) <a href="https://twitter.com/phi_lira/status/1215231019294560256?ref_src=twsrc%5Etfw">January 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

現在は[master](https://github.com/Unity-Technologies/ScriptableRenderPipeline)ブランチと[release/2019.3](https://github.com/Unity-Technologies/ScriptableRenderPipeline/tree/release/2019.3)ブランチにマージされました。以下はそれぞれのブランチに対するPull Requestです。

* [Universal Camera Stacking by phi-lira · Pull Request #5260](https://github.com/Unity-Technologies/ScriptableRenderPipeline/pull/5260)
* [Universal/2019.3/backports by phi-lira · Pull Request #5462](https://github.com/Unity-Technologies/ScriptableRenderPipeline/pull/5462)

またドキュメントは[com.unity.render-pipelines.universal/Documentation~/cameras.md](https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/master/com.unity.render-pipelines.universal/Documentation~/cameras.md)に用意されています。

# Camera Stacking System

## 環境

* Unity2019.3.0f3
* [release/2019.3ブランチ](https://github.com/Unity-Technologies/ScriptableRenderPipeline/tree/release/2019.3)のUniversalRP 7.2.0
* [Unity Samples: UI](https://assetstore.unity.com/packages/essentials/unity-samples-ui-25468) (動作確認用)

## UniversalRPのダウンロード

zipでダウンロードする方法とgitでcloneする方法、更にgitで対象のフォルダのみcloneする方法がありそれぞれ利点、欠点があるので使いやすい方法を選んでください。

* zipでダウンロード
    * 利点: ブラウザからダウンロードできる
	* 欠点: zipのサイズが1GB程度ある
* gitでclone
	* 利点: git logを辿れる
	* 欠点: zipよりもダウンロード時間が長いのでおすすめしない
* gitで対象のフォルダのみclone
	* 利点: 必要最小限のフォルダのみダウンロードするので速い
	* 欠点: gitといくつかのコマンド操作が必要なので慣れていないと操作が難しい

### zipでダウンロードする

以下のリンクから`release/2019.3ブランチ`を開き、右側の`Clone or download` > `Download ZIP`ボタンからダウンロードします。

https://github.com/Unity-Technologies/ScriptableRenderPipeline/tree/release/2019.3

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/7f621e52-4cff-2855-81e5-f4759039e83b.png)

### gitでcloneする

以下のコマンドでuniversal/camera-stackingブランチをcloneします。

```sh
git clone -b release/2019.3 https://github.com/Unity-Technologies/ScriptableRenderPipeline.git
```

### gitで対象のフォルダのみcloneする

以下のコマンドでCore RP Library, Universal RP, Shader Graphのみcloneします。

```sh
# 不要なfetchしないためにリモートのみを設定したローカルリポジトリを作る
git init ScriptableRenderPipeline
cd ScriptableRenderPipeline
git remote add origin https://github.com/Unity-Technologies/ScriptableRenderPipeline.git

# sparse checkoutを有効にしてCore RP Library, Universal RP, Shader Graphのみをcheckout対象にする
git config core.sparsecheckout true
echo /com.unity.render-pipelines.core/ > .git/info/sparse-checkout
echo /com.unity.render-pipelines.universal/ >> .git/info/sparse-checkout
echo /com.unity.shadergraph/ >> .git/info/sparse-checkout

# checkoutしたいブランチと同名のローカルブランチを作る
git checkout -b release/2019.3

# shallow cloneで履歴を1つだけpullする
git pull --depth 1 origin release/2019.3
```

## UniversalRPをインストールする

以下のように`com.unity.render-pipelines.core`, `com.unity.render-pipelines.universal`, `com.unity.shadergraph`を`[Project Folder]/Packages`にコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/dce1d3f4-d293-2b42-d84d-8aadf357cabb.png)

正常にインストールできているとPackage ManagerのCore RP Library, Universal RP, Shader Graphのバージョンが7.2.0 (in development)になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/50826043-925a-46f1-1cf2-49fb635d8c0f.png)

## 従来のRP

まずは確認のために[Unity Samples: UI](https://assetstore.unity.com/packages/essentials/unity-samples-ui-25468)のMenu 3Dを開いてみます。このシーンは背景用の`MainCamera`とUI用の`GUI Camera`の2つがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/76d9d192-8b7e-12f2-3160-f00b559748af.png)

## Camera Stacking System未対応のUniversal RP

次にCamera Stacking System未対応のUniversal RP 7.1.2 で確認するとGame ViewはGUI Cameraで背景も上書きされてしまいます。
描画順序は従来のRPと同様にDepthで決まるようですがUniversalRPに切り替えるとInspectorから見えなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/fdf0f6f3-d35c-6ed4-8f71-08c760594821.png)

## Camera Stacking System対応のUniversal RP

1. ~~まずはUniversalRPのアセットを作り、`Opaque Texture`を有効にします。これは1パスしか扱えないUniversalRPでGrabPassと同様の機能でカメラスタックに必要なようです。~~ **`Opaque Texture`を有効にしなくても描画されるようになりました。**<details><summary>UniversalRPアセット</summary>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/f43e2605-b97c-d9b1-915a-f4e6b6bcd7c8.png)
</details>
1. 後から描画するカメラ(GUI Camera)の~~`Background Type`を`Uninitialized`か`Solid Color`に変更して~~`Render Mode`を`Overlay`に変更します。
~~`Render Mode`を変えると`Background Type`が見えなくなるので必ず`Background Type`を先に変更します。~~
**事前に`Background Type`を変更しなくても背景が上書きされなくなりました。**
    * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/e5bb2efa-9506-90f7-cc72-b792def93e00.png)
1. 先に描画するカメラ(Main Camera)の`Stack`に`GUI Camera`を追加します。
    * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/8badbee4-adcd-7a00-f5e7-d3f3c40600c6.png)

以上の設定でUniversalRPでも従来のRPと同様に複数のカメラを重ねて描画できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/a4193bd5-c7eb-301b-90c1-a1b5533c8ebc.png)

# 他の方法でカメラスタックする

こちらは試していませんがLWRPを拡張する方法とPostProcessingとしてオーバーレイする方法もあります。
ですがLWRPの拡張はv3あたりがベースなのでそのまま使えるか分からなかったりPostProcessingは遅かったりとなかなかうまくいかないようです。

* [LWRPのパス拡張について](https://www.slideshare.net/kairimineiri/lwrp-137342815/30)
* SRP Post Processing Texture Overlay in Unity
	* https://forum.unity.com/threads/glitching-with-multiple-cameras-lwrp.592477/page-2#post-4838468
	* https://www.youtube.com/watch?time_continue=413&v=LkP2AHcokxA
	* https://assetstore.unity.com/packages/tools/particles-effects/post-processing-texture-overlay-147951
	* https://github.com/ditzel/PostProcessingTextureOverlay
* [【Unity】LWRPでポストプロセスを使用しつつUIの手前にパーティクルを表示する](http://tsubakit1.hateblo.jp/entry/2019/10/09/233225)

# 最後に

Unityの中の人によると以下のスレッドでUnity2019.4LTSを目標としていて2019.3リリース直後にパッケージに含まれそうと言っているので期待できそうです。

* https://forum.unity.com/threads/glitching-with-multiple-cameras-lwrp.592477/page-2#post-5125979
* https://youtu.be/mKhSt7og0XY

# 参考リンク

* [Camera Rendering in LWRP](https://docs.google.com/document/d/1GDePoHGMngJ-S0Da0Fi0Ky8jPxYkQD5AkVFnoxlknUY/edit)
* https://portal.productboard.com/8ufdwj59ehtmsvxenjumxo82/c/31-camera-stacking
* Camera Stacking Systemの動画
	* https://drive.google.com/file/d/1J8ChJIsAXdXdmOPtNF_FIqd9exYD0kql/view
	* https://twitter.com/pigeon6/status/1121268133530984449
* [Universal Camera Stacking by phi-lira · Pull Request #5260](https://github.com/Unity-Technologies/ScriptableRenderPipeline/pull/5260)
* [Universal/2019.3/backports by phi-lira · Pull Request #5462](https://github.com/Unity-Technologies/ScriptableRenderPipeline/pull/5462)
* [LWRPのパス拡張について](https://www.slideshare.net/kairimineiri/lwrp-137342815/30)
* SRP Post Processing Texture Overlay in Unity
	* https://forum.unity.com/threads/glitching-with-multiple-cameras-lwrp.592477/page-2#post-4838468
	* https://www.youtube.com/watch?time_continue=413&v=LkP2AHcokxA
	* https://assetstore.unity.com/packages/tools/particles-effects/post-processing-texture-overlay-147951
	* https://github.com/ditzel/PostProcessingTextureOverlay
* [【Unity】LWRPでポストプロセスを使用しつつUIの手前にパーティクルを表示する](http://tsubakit1.hateblo.jp/entry/2019/10/09/233225)