【VRChat】PostProcessingを使ってワールドをより良くする

# 概要
「Lightingもある程度理解したし、なんかもっとワールドいい感じにしてー」みたいなのありますよね。
そこで、この**Post-processing**というものを適切に使えば、より良い絵作りができると思います。

:::note warn
この記事はUnityやVRChatワールドの基本的な作り方を理解している人向けです。
個人的にはライトベイクやReflection Probeを理解してからPost-processingに手を付けるべきです。
:::

## 解説について
・一応VRChatのワールド向けに書いていますが、PostProcessing自体はUnity側の機能なので、それ以外でも使えます。
・今回の記事ではVRChat上で主に使うであろう **Bloom** と **Color Grading** について解説します。
## 環境
・Unity2018.4.20f1を使用
・VRCSDK2-2020.11.16.12.43_Publicを使用
・PostProcessingStack V2を使用

:::note info
この記事の解説ではVRCSDK2を使用していますが、VRCSDK3でもVCC導入後でも同様の方法で実装が可能です。
また、Unity2022でもほぼ同様の方法で実装可能です。
:::

# Post Processingってなに？
Post-processing（ポストプロセス）とはカメラの画像にフィルターとかエフェクトを適用する処理のことです。取り合えず、適切に使えばなんかよりいい感じの絵になるやつだと思っておいてください。
ただし、**掛け過ぎると目が痛くなったり、酔う原因にもなるので（特にVRだと）** ので注意してください。[詳しくはこれ読んで。](https://docs.unity3d.com/ja/2018.4/Manual/BestPracticeMakingBelievableVisuals8.html)
※以下からPost-processingのことを「PPS」と略します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/b8129b46-4cc2-4f3c-952b-8fe9f36a685f.png)
↓ PPSを掛けると…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/0361724e-d799-f5c6-7194-300dbf3a8b3e.png)


ポストプロセスの重要性や実際現場でどのように使われているかについては以下の記事を読めばなんとなく分かると思います。

https://automaton-media.com/articles/newsjp/20240511-293086/


# 1. PPSv2の導入方法
1. Unityを開き、`Window` → `Package Manager`を選択し、開きます。

2. 導入可能なパッケージの一覧が表示されます。その中から「PostProcessingStack」を見つけてインストールを行います。

3. 「PostProcessingStack」の横にチェックマークがついていれば、PPSの導入は完了です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/868b7fac-46cc-c3b9-51f4-4210c8de530e.png"width=50%>



# 2. PPSを適用する前の準備
面倒くさいので機嫌がいい時にやりましょう。
3ステップあります。遅くても20分程度で済むと思います。

## 2-1. レイヤーの設定を行う

`Edit` → `ProjectSettings` → `Tags and Layers`を選択し開きます。
もしくは適当なオブジェクトの`Inspector`にある`Layer`をクリックし、`AddLayer`をクリックでもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/3325689f-938a-b5b7-26be-3803d7688935.png)

Unity2018では標準で「PostProcessing」というレイヤーがあるのでそれを使うのもありですし、自分で新たに作るのでもどちらでもOKです。今回は標準で用意されている「PostProcessing」のレイヤーを使用します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/8beaa098-8573-f2ee-73ce-0a8cf8dd80dd.png"width=70%>




## 2-2. MainCameraの設定を行う

1. Main Cameraをクリックし、`AddComponent` → `Post-process Layer`を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/1fef5187-dcb9-b7da-882b-cd9a1d5adbbe.png)

2. 先ほど追加した`Post-process Layer`の設定を行います。TriggerにはMain Cameraを、Layerには先ほど設定したレイヤーを設定します。今回の場合だと「PostProcessing」というレイヤーを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/ba70d9c4-2e00-f25c-4fe2-fb807255def3.png)

3. 次に`Post-process Layer`を設定したカメラ（今回だとMainCamera）をVRCWorld Prefabの`VRC Scene Descripter`の`Reference Camera`に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/30770749-4125-96fa-8082-8dd3a42c09e9.png)


## 2-3. 空のオブジェクトを作る

1. 次にHierarchyの`Create` → `Create Empty`で空っぽのオブジェクトを作成します。名前は分かりやすく「PPS」とでも名付けておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/63a16cba-8da2-b9ed-6427-1cf28d8272b6.png)

2. 先ほど「PPS」と名付け追加した空のオブジェクトをクリックし、`AddComponent` → `Post-process Volume`を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/6a40ea90-dbe2-bda3-c89a-60c359b67644.png)

3. Post-process Volumeを追加したオブジェクトのLayerを [2-1.レイヤーの設定を行う](https://qiita.com/sudare222/items/5be4b93de07dc3d7fd02#2-1-%E3%83%AC%E3%82%A4%E3%83%A4%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E8%A1%8C%E3%81%86) で追加したレイヤーに設定します。
(今回だと「PostProcessing」というレイヤー)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/c24c6a35-8ecf-7464-c09d-2ad04168101d.png)

4. 「Post-process Volume」の設定を行います。
まず、`Is Global`にチェックを入れます。これにチェックを入れることで**ワールド全体**にエフェクトが掛かります。
逆に「ワールド全体に掛けたくない！」「一部の部屋にだけ掛けたい！」といった場合はチェックを外しましょう。PPSの切り替えやワールドの一部にだけ掛ける方法は後述します。

5. 最後です。
`Profile`の横にある`New`をクリックします。そうすることで`Profile`が新たに作成されます。
この`Profile`を使って各種エフェクトの設定を行っていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/be437eac-fdae-71d4-85dc-127c43889d03.png)
**※上の画像ではLayerが「Default」になってますが、「PostProcessing」が正しいです。**

:::note warn
PPSの各種設定は各オブジェクトごとに設定されているのではなく、あくまでもProfileで管理・設定されているので複数の違うPPSを掛ける場合は、それごとにProfileを作る必要があります。
なので、さらに新しく違う効果のPPSを作る場合はProfileも新たに作成してください。
:::

**これでめんどくさい各種設定が終わりました！！**

# 3.画面にエフェクトを掛ける
## 3-1. まず初めに

これからお待ちかねのPPSを使って画面にエフェクトを掛けていこうと思います。サンプルとして[私のワールド](https://vrchat.com/home/world/wrld_8321234c-0fdb-4a9d-af45-c5d4a5790871)で見ていこうと思います。下の図はPPSを一切掛けていない素の状態です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/3ca3a865-57b0-0539-1244-54f643300408.png"width=70%>

`Post-process Volume`の`Add effect`をクリックしてください。すると「なんのエフェクト追加すんの？」と聞かれるので選択しましょう。まずは`Bloom`を選択したいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/a3da2698-94a0-07f5-b0b2-3c5f551e3cb1.png)

選択をすると以下の様なものが出ると思います。
今回はさらに`Color Grading`というものも使用するので、もう一度Bloomの項目の下にある`Add effect`をクリックして同様に追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/07f01416-ec40-0496-cdef-5ebc6a908eb9.png)


**今回は具体的な数値などについては省きます。** めんどくさいので……
Bloomについて簡単に説明すると「明るい部分をより光らせて、強調する」機能だとふんわり思ってもらえればいいと思います。
Color Gradingは色調補正をする機能だと思ってください。


## 3-2. Bloomってなに？

主に弄るであろうBloomの設定について雑に説明すると

| 名称 | 説明 |
|:--|:--|
|Intensity   |光の強さ。最大でも2程度に留めておいた方が良い。   |
|Threshold   |どの程度の明るさであるならばエフェクトを掛けるのかを決める。この値未満の明るさのものにはエフェクトが適用されなくなる。数値が低すぎると全域が光って眩しくなるので注意。|
|Soft Knee|Thresholdの閾値をなだらかにする。|
|Clamp|Bloomの量。一度0にしてから徐々に数値を上げて調整しましょう。|
|Diffusion   |光のにじむ強さ。  |

なのでこんな感じで数値を極端に弄ると……
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/2f47ffd9-7fa7-8e8a-5b7a-e9d449675fc7.png)

**こうなる↓(極端な例なのでマネしないで)**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/38d6ca9d-9622-c723-8820-7ed97adbec63.png)
VRで入ると目が痛すぎて大変なことになるのであまりにも強くするのはやめときましょう。

個人的には、あくまでも **明るいところをより明るく、強くBloomを掛ける** 為に使うものだと思っているので、画面全体的に掛かる設定はしない方が良いと思います。（この辺は人それぞれで宗派みたいなのがある）


### 自己発光マテリアルを使用した表現

上の図を見ると「極端に光っているところとそうでないところがあるけど、何が違うの？」となる方がいる思いますが、これはPPSの設定の違いではなく、**マテリアルの設定の違い**です。間接照明の表現だったりに使えると思います。

(左側Bloomなし / 右側Bloomあり)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/a5864d70-39af-2eab-56a8-cc41f0dfe8d0.png)

この光の表現を行うには[自己発光マテリアル](https://docs.unity3d.com/ja/2018.4/Manual/StandardShaderMaterialParameterEmission.html)が必要になります。
設定は簡単で、まずはStandardシェーダーのマテリアルを作成します。そして`Emission`にチェックを入れれば自己発光マテリアルの完成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/b666ebc2-39da-c85a-b892-4afecf6ba071.png)

発光する色を指定したい場合は`Emission`下の`Color`を、発光する強さ変えたい場合は`Intensity`を弄りましょう。
自己発光マテリアルの発光度合い(強さ)だけを強くしたい場合は、
<font color="Red">**Bloom側のIntensityを強くするのではなく、自己発光マテリアル側のIntensityを調整する**</font>ことをおすすめします。

Global Illuminationは通常のライトと同様で`Realtime`と`Baked`があり、ライティングが分かる方ならこの説明で分かる思います。分からない方は軽量化のため`Baked`にしちゃいましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/7412b067-8455-13fd-b783-bb10bad55ac3.png)

具体的な活用例記事は[こちら（別記事）](https://qiita.com/sudare222/items/b71c6b75f3e9cc7a461b)



## 3-3. Color Gradingってなに？

Color Gradingは画面の色調補正をする機能です。
Color Gradingは弄れば多少分かると思うのでさらに雑に説明すると

| 名称 | 説明 |
|:--|:--|
|Colorf Flter   |設定した色を画面全体に掛ける   |
|Saturation   |彩度の調整   |
|Contrast   |コントラストの調整   |
|Post-exposure(UV)  |画面の明るさの調整   |

Post-exposure(UV)は値をマイナス方向へ弄れば、睡眠ワールド等にあるナイトモードとして使えると思います。

なのでこんな感じで数値を極端に弄ると……
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/20c5fa42-5352-e02d-613e-fb8e419c6aaf.png)

**こうなる↓**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/67beed51-ce51-f5a9-6f7d-62bfa2b055ba.png)

こちらもあんまり極端に弄ると目に悪くなるので気をつけてください。

## 3-4. 参考例
私がVRChatで公開しているワールドのPPSの設定例を示します。あくまで参考例ですので、自分で色々試行錯誤してみてください。
これが正しいわけではないです。多分もっといい設定がある……

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/b29f0e92-da0b-7c6b-8519-420f95af94e6.png)

(左側PPSなし/右側PPSあり)
![PPS1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/a5a4f22b-76af-5913-d368-3d4f9b571528.jpeg)

Bloomで間接照明やライトの光を軽く強調させ、Color Gradingで薄くオレンジ色の色調にしています。

以上でPPS(BloomとColor Grading)の基本的説明は以上になります。PPSには他にも様々なエフェクトやフィルターがありますが、**VRでは非推奨・非対応**なものがほとんどなので、使う機会はないと思います。
PPSを理解して、ワールドに設定するとめちゃくちゃ雰囲気がよくなるので是非覚えてくださいねー。


# 4. VRCワールド内で複数のPPSを使い分けたい・切り替えたい
ここからは応用編です。
VRChatのワールドでボタンを押すことでナイトモードが起動したり、違う部屋に移動すると掛かっているPPSが違うことがあると思います。ここからはその導入方法について書こうと思います。

## 4-1. PPSのON/OFFをする
PPSのON/OFFをするのに特に難しいことは必要なく、原理としてはミラーのON/OFFと全く一緒です。
2-3の空のオブジェクトを作る で作成した`Post-process Volume`を追加したオブジェクトを ~~VRC_TriggerのSetGameObjectActiveでオンオフするだけです。何もPPS側で弄る必要はありません。VRC_Triggerの使い方については自分で調べてください。~~
（鏡のON/OFFと同じ原理で可能。ギミックの作り方は各自で調べて。）

## 4-2. ワールド内で複数のPPSを同時に使い分ける
同じワールドで部屋ごとに違うPPSが使われていることがあると思います。ここではその導入方法を説明します。
初めに使い分けたいPPSの`Is Global`のチェックを外し、`Add Component`から`Collider`をアタッチします。`Collider`の形はなんでもOKです。
このCollider内にカメラが入るとそのPPSが適応されます。
`BlendDistance`を設定することで距離に応じた強さでPPSが適応されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/bd50ddd7-a6cf-4cc7-9b07-831430a5c52d.png"width=80%>


しかし、**このままだとアタッチしたコライダーが通常通り動作し、衝突してしまう** ので、「部屋に入れなーい」といった状況になります。次に、そうならないための設定を行います。

`Edit` → `ProjectSettings` → `Physics` → `Layer Collision Matrix` を開きます。そしてPPSのコライダーが衝突しないように、`Post-process Volume`が追加されているオブジェクトの`Layer`のチェックを外します。(今回は「PostProcessing」というレイヤー)とりあえず、以下の様に全部外していいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/f27c4a9b-fb6a-f128-63b0-c98405b45ab7.png)

以上で設定は完了です。
下のGIFを見てもらうとカメラがCollider内に入った時にだけ、PPSが有効化されていることが分かると思います。
![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/00963ae8-0925-2cbd-2d17-8f801b48e518.gif)

# 【トラブル】Scene上で見てもPPSが適用されない！！
もしかするとUnityのSceneでPPSが適応された結果が見えない場合があるかもしれませんが、~~その場合はScene上部にある風景画(?)のアイコン横の▼をクリックしてPost Processingsにチェックが入っているか確認してください。~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/0b609203-db07-e19f-1201-104a813d72a8.png)


Unity2022の場合は、Scene上部の:sparkles:マーク的なのが入っているアイコン横の▼をクリックしてPost Processingsにチェックが入っているか確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1303641/ad1163ce-ff57-1a91-c25e-61d82445df74.png)



# 参考記事
- [Unity ルックデヴ講座 Post Processing Stack v2編](https://gaprot.jp/2018/08/01/unity-lookdev-post-processing-stack-v2/)
- [UnityDocumentation Emission](https://docs.unity3d.com/ja/2018.4/Manual/StandardShaderMaterialParameterEmission.html)
- [UnityDocumentation Bloom](https://docs.unity3d.com/ja/2017.4/Manual/PostProcessing-Bloom.html)