ShaderGraphでポストエフェクトを適用する【Unity、Fullscreen ShaderGraph、グレースケール】

# ■ 概要
本記事では、UnityのShaderGraphを使って
シーン全体に効果を適用するポストエフェクトを実装するにあたって、
Unity2022.2以降に追加されている機能「Fullscreen ShaderGraph」の
導入手順を解説します。
また今回はサンプルでグレースケール化の実装も行います。

# ■ 環境

Unityバージョン　：　Unity2022.2.12f1
プロジェクトテンプレート　：　3D（URP）

**今回はShaderGraphの機能が標準で搭載されている**
**「URP」レンダリングパイプラインのプロジェクトで解説していきます。**

（「URP」や「HDRP」の概要、導入方法については[こちらの記事が参考になります。](https://ja.wikipedia.org/wiki/OpenSound_Control)）

**「Fullscreen ShaderGraph」は「URP」と「HDRP」両方の**
**レンダリングパイプラインのプロジェクトに対応していますが**
**導入手順が多少異なるみたいです。**


# ■ Fullscreen ShaderGraphの導入手順

導入手順はざっくり以下の通りです。

1.　Fullscreen ShaderGraphの作成
↓
2.　Full Screen Pass Renderer Featureを設定
↓
３.　ShaderGraphでポストエフェクトを作成


## 1.　Fullscreen ShaderGraphの作成

今回はUnityのプロジェクトテンプレートから「3D（URP）」で空のプロジェクトを作成し、
それっぽいオブジェクトを配置してみました。

こちらがGame画面です。
![Screenshot_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/171ac78f-fcfb-9128-72c4-7b137e8d3a92.png)


`Create -> ShaderGraph -> URP -> Fullscreen ShaderGraph`を選択し、
Fullscreen ShaderGraphファイルを作成します。

![Screenshot_1.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/f4fa83e4-f9dc-8ca0-57f8-8e1f7ad7244f.png)

作成するとこんな感じでShaderGraphのファイルと、
それを適用したMaterialが生成されます。

![Screenshot_２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/62151ee5-171b-15b9-a5da-216ef79dcb34.png)


## 2.　Full Screen Pass Renderer Featureを設定

`Universal Renderer Data`の
`Add Renderer Feature　->　Full Screen Pass Renderer Feature`を選択し、
↑で作成したFullscreen ShaderGraphを適用したMaterialをセットします。

![Screenshot_３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/ab041d21-4a3a-4baf-095e-91f4c60da399.png)

プロジェクト内でどの`Universal Renderer Data`が適用されているかを確認するには、

１.`ProjectSettings -> Quality -> Rendering -> Render Pipeline Asset`
から使用している`Universal Render Pipeline Asset`を選択。



![Screenshot_４.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/37e30fac-b85a-123e-dad8-6441a2cdfacb.png)

↓

2.インスペクター上から`Rendering -> Renderer List`に設定されている
`Universal Renderer Data`を確認

![Screenshot_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/357495c2-c913-e493-f65a-e1339200173e.png)


の手順で確認ができます。

## ３.　ShaderGraphでポストエフェクトを作成

今回は簡単にグレースケールのポストエフェクトを作成しようと思います。

### ・　画面の入力をそのまま出力する


ShaderGraphを作成した直後は、単色の灰色が適用されており
画面全体が灰色になってしまっているので、まずは画面の入力をそのままスルーさせる
ポストエフェクトを作成します。

それがこちら。
![Screenshot_６.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/e0d74ed8-4dbe-3462-5e8f-39e7734c7981.png)

>１.`URP Sample Buffer`ノードを作成
>↓
>2.`Source Buffer`を`BlitSource`に設定して画面の色情報を取得
>↓
>3.そのままFragmentシェーダーに渡す

シーンそのままの何も効果がかかっていないポストエフェクトが適用されます。
![Screenshot_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/d09fcc0f-03bd-26cb-e168-ac9a309e5763.png)

### ・　グレースケールのポストエフェクトを適用する

本題に戻ってグレースケールのポストエフェクトを適用します。

実装はこちら。
![Screenshot_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/04a05d3d-a214-fddd-9732-5df3493e1421.png)


アプローチとしては、ビクセル毎にそのピクセルのrgb値それぞれの値を加算して
その合計を3で割ればグレースケール化できますが、
rgb値にそれぞれ0.33を掛け、それらを合計しても同様の結果が得られるため
`Dot Product(内積)`のノードを使用してグレースケール化します。

またグレースケール化にあたって、より自然に効果をかけるために加重平均を用いるのが
一般的なので`Dot Product`のノードを使用した方が加重平均をかけやすいです。

***
### ※加重平均について

グレースケール化における加重平均については[こちらの記事が参考になります。](https://talavax.com/grayscale2.html#gsc.tab=0)
例えば、ただのRGBブルーとRGBグリーンですが
どちらの方がより明るく見えるでしょうか。
![gb.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/35436a3b-decd-a3e7-69c2-5dea55292cd5.gif)
rgbの色に対して人間の目の認識にはズレがあり、
グリーンの方がより明るいと感じるはずです。

人間の認識に適したrgb値の重み付けで平均をとることによって
結果的により自然な見た目になるといった感じです。

***

`Dot Product`のノードを使用して、加重平均でグレースケール化します。

![Screenshot_7.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/c7be66ea-c96c-9c1b-0947-251bc5a6f7ee.png)


`Dot Product`のノードの1つ目のinputに画面の色情報を入力し、
２つ目のinputに加重平均の係数を入力します。

>`X` (RED) → 0.299
>`Y` (GREEN) → 0.587
>`Z` (BLUE) → 0.114
>`w` → ここは0を入力します
>
>（この重み係数はより自然にグレースケール化されるものとして定められているものです。）

結果をGame画面で確認します。

![Screenshot_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/bd8a7701-c11f-85ee-c361-74cb5098c524.png)

グレースケールのポストエフェクトが綺麗にかかりました。


# ■ 最後に （感想）

スタイライズ系のエフェクトを画面全体にかけたい場合は
こんな感じで比較的簡単に実装できると思います。
あとは画面全体にオーバーレイのエフェクトを適用できるので
画面遷移の演出とかにも使えそうだなぁと思いました。
最後まで読んでいただきありがとうございました。