Sleek Render 解体新書

#はじめに
この記事は事実上[リリース済みSteamVRゲームをQuestに移植した話](https://qiita.com/GONBEEE_project/items/590405a1f514559712c5)の続編になります。
上記内で言及した
**[Sleek Render: Mobile Post Processing Stack](https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/sleek-render-mobile-post-processing-stack-103628)**
の解説記事となります。
上記記事を先に読むことをおすすめします。

#Sleek Renderとは
Sleek Render: Mobile Post Processing Stackはその名の通りモバイル向けのポストプロセスアセットです。
**超軽量**を謳っており、モバイルデバイスに最適化されていることを全面に押し出しています。
使い方や機能から考えるに、Unity公式提供の[PostProcessingStack v1（旧式）](https://assetstore.unity.com/packages/essentials/post-processing-stack-83912)の簡易版として開発されている雰囲気を感じます。
モバイル向けではありますがPCでも動作するのでUnity提供PPSが重い際の軽量化手段としても使えるかなという感じです。
価格も$19と手頃？なお値段です。
注意点として
**どのVR形式もサポートしていない**
**Lightweight Rendering Pipelineもサポートしていない**
と公言されています。詳しくは後述しますが、少なくとも**OculusQuestでは動作確認できました**。

#検証環境
Unity2018.3.14f1
適当なシーンを構築して、メタリックなオブジェクトやHDREmissionなオブジェクトを設置します。
こんな感じのシーンを用意しました。これをベースにエフェクトをかけていきます。
![bandicam 2019-06-21 13-20-14-195.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/903e6a3b-e194-8e6a-9663-0752d30f0718.png)

各オブジェクトのマテリアル設定は以下の通りです。
CapsuleのみReflection Probeを設定しています。
![SnapCrab_2019-06-21_13-08-40_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/523e08a1-922e-4854-4706-d377ffb523d1.png)
#適用方法
使い方はUnity公式PPSv1と非常に似ています。
適用させたいCameraコンポーネントを持つGameObjectに`SleekRenderPostProcess`コンポーネントを貼ります。
![SnapCrab_2019-06-21_15-58-30_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/5223e836-fb50-1c6c-1ea6-9f3e6f6714b9.png)
貼った直後はDefault Settingsプロファイルが適用されます。
これは全てのエフェクトを盛ったプロファイルなので、画面が少々汚くなります。
![bandicam 2019-06-21 15-57-11-502.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/ab13f800-5c7e-cfca-9052-c8ced7af5091.png)

`SleekRenderPostProcess`コンポーネントにあるSettings欄でプロファイルを参照します。
公式PPSv1と同じくD&Dで設置、もしくは右端の◎から選択します。

#プロファイル詳細
ここからはプロファイルの中身について記していきます。

プロファイルを作るにはProjectビューで右クリックして、`Sleek Render Settings`を押します。
![InkedSnapCrab_2019-06-21_16-09-29_No-0000_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/1741585e-e554-618b-4828-44083830b5cc.jpeg)
公式PPSv1と同じようにプロファイルが作られるので、任意の名前を指定して保存しましょう。
作られてすぐのプロファイルはDefault Settingsとなっています。
先程適用した時に画面が汚くなったプロファイルのコピーです。
見ての通り、全てのエフェクトがアクティブになっています。
![bandicam 2019-06-21 16-12-46-664.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/c47dfa93-4165-1598-9a57-a68682f57e24.png)

##Bloom
公式PPSv1でいうBloomです。そのままです。英語の意味としては”花が咲く””光などが照り映える”などがあります。
画面内で発光している所をぼんやり輝かせるエフェクトです。
![SnapCrab_2019-06-21_17-24-02_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/fcc006ad-54e7-7955-9043-8a1a0e9e402a.png)
左がSleek RenderのBloom、右が公式PPSv1のBloomです。

###Bloom threshold / Bloom intensity
これらは公式PPSv1とほとんど同じです。
それぞれどこから発光させるかの閾値と、発光の強さの指定です。
注意点というほどでもありませんが、Sleek Renderの方がintensityの反応が強めです。上げるとすぐに明るくなります。
Bloomとしてあるべき姿は以下の通りです。キレイですね。
これは threshold = 0 , intensity = 1 です。
**Bloomパートではこの画像の設定をリファレンスとして進めます。**
![bandicam 2019-06-21 18-06-58-549.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/57f1d854-c699-cd14-c6bf-56af4c4abb80.png)

thresholdを1（最大値）に設定すると一切光らなくなります。1未満に設定しましょう。

intensityは発光の強さというより、上に重ねる色の強さの指定です。
試しに threshold = 0 , intensity = 0 に設定してみましょう。不思議な絵になります。
![bandicam 2019-06-21 18-02-49-765.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/11921c5e-334a-7261-05fb-c887871938e9.png)
これは恐らく**黒く発光している**という捉え方ができます。
本来黒は光を0にすると表現できる色で、Sleek Renderでの intensity = 0 は**光が0**というような表現になります。
公式PPSv1でintensityを0にしてもこのような絵にはなりません。
正確な言語化ができません。伝わってください。
0にするとこういう絵になる、ということを知っておけば何らかの場面で活かせるかもしれません。

###Bloom tint
これは発光の方向性の色です。前述の項目では白(255,255,255)でした。アルファは無関係です。
”どの色を強く発光させるか” ”どの色を乗せるか”という捉え方をしてください。これもまた言語化が難しいです。
見たほうが早いです。試しにBloom Tintを赤(255,0,0)にしてみます。
![bandicam 2019-06-24 13-11-19-250.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/0f3db94a-944f-877f-c7b6-fb4028b39869.png)
全体的に画面が赤味がかり、緑や青の部分は threshold = 0 , intensity = 0 のような黒い表現になります。
threshold = 0 , intensity = 1 のとき赤色だった部分はキレイに発光し、白くブルームがかかっていた部分が少し赤く染まっています。
後述するColorizeとの使い分けが難しそうですが、ColorizeだとBloomの色ごと変更してしまうので
使えるシーンとしては、例えば警報装置とか特定の色の光を当てている状況などで使えるのではないかと思います。

参考に青、緑も乗せておきます。赤が黒く染まらないのはMaterial設定で特に強くHDR発光しているからかと思います。
![bandicam 2019-06-24 13-32-53-429.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/915ef250-6c39-1f6b-33e5-6af6f90fd8a8.png)
![bandicam 2019-06-24 13-33-02-789.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/8e075a80-382f-a9fd-a5f2-7a6a586e8c80.png)

###Bloom texture size
これは公式PPSv1で相当するものがありません。強いていうなら Radius が近いかなと言う感じですが、
単純に発光サイズが上がるのではなく、**密度が下がりながら広がる、密度を上げながら狭める**という反比例の関係にあります。
Preserve aspect ratio = true, Y = 164 で試してみます。
![bandicam 2019-06-24 13-43-02-001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/ff1ff98e-5df3-022b-330f-67fc26720d72.png)
ちょうどいい発光感です。
次に Y = 32 で試してみます。
![bandicam 2019-06-24 13-45-41-544.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/577f3a12-0785-46d7-c1ac-a3c6fac14854.png)
全体的に発光密度が下がり、範囲が広がったのが分かると思います。
単純に発光サイズを変えるわけではなく、**発光密度は固定で範囲を決めるもの**と考えられます。
そのためキレイに見せるには **Y はなるべく大きな数字のほうがいいと思います。**

またパラメータに Preserve aspect ratio というものがありますが、
これは発光範囲をX,Yでそれぞれコントロールするか否かの設定です。
よっぽどのことがない限りここは true で問題ありません。

###Bloom passes
これも公式PPSv1で相当するものがありません。強いていうならやはり Radius です。
発光の密度を操作します。単純に重ねるだけではなく、少しズレて上乗せされるので
上述の Bloom texture size に影響があります。
選択可能なのは 3 or 5 で、5のほうが負荷が高く全体的にぼんやり写ります。
5にすると輪郭が更にボケるので、眠い絵になります。個人的には3のほうがシャープで好きです。
Bloom texture size Y = 164, Bloom passes = 5 の写り方と
Bloom texture size Y = 80, Bloom passes = 3 の写り方がほぼ一致します。
![Inkedbandicam 2019-06-24 15-07-32-459_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/e00541e8-4145-bd92-74d0-6e2de71545d2.jpeg)
![Inkedbandicam 2019-06-24 15-07-18-879_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/3529c5ed-a43d-e51b-ea92-f28e48c82926.jpeg)

###Brightpass Luma calculation
![SnapCrab_2019-06-24_15-21-12_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/4c0b7a1a-281c-1676-0c6c-c0d8c21dda2a.png)
**結局調べてもよくわかりませんでした。**
設定項目からするに表現するカラースペースの違いかと思われます。
Uniform, SRGB, Custom とあり、Uniform は UniformColorSpace、SRGBは sRGBColorSpaceのことだと思います。
Customというのが謎で、Vector3が出現します。正規化されていないベクトルを入力すると怒られます。

![SnapCrab_2019-06-24_16-49-45_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/bcd1e6c4-5c23-5487-847b-4b4c71df4f94.png)
おとなしくUniform か SRGB を選ぶことをおすすめします。
SRGBの方が公式PPSv1の見栄えに近づきますが、輪郭が少しボケます。
Uniformだとくっきり輪郭が見えますが、少し発光が弱くなった気がします。
![Inkedbandicam 2019-06-24 16-54-35-538_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/2068939b-f8bf-aa07-6072-903ee02c4987.jpeg)
![Inkedbandicam 2019-06-24 16-54-39-809_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/cc568f3e-6495-4295-ccf8-92941f394ef0.jpeg)
Cygamesのエンジニアブログが参考になりそうでした。
http://tech.cygames.co.jp/archives/2296/

##Colorize
公式PPSv1で言うところのColor Gradingに相当すると思いますが、見ての通りとんでもなくシンプルになっています。
![SnapCrab_2019-06-24_17-02-31_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/fbb8becc-206f-13fb-26fd-d5b0571bea6c.png)

やっていることはただの着色フィルタです。ただ1つのカラーしか設定できず、本当にシンプルです。
公式PPSv1の大量の設定項目をキレイに設定できるのはデザイナだけで、
プログラマにとってはこのくらいでちょうどいいのかなと思ったりします。
色設定でアルファを0にするとエフェクトがかからなくなります。255にすると全てがその色で染まります。
例えば水色(0,150,255,255)にしてみます。Bloomは切ってあります。
![bandicam 2019-06-24 17-07-22-451.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/9bf816c8-c730-2b24-a5d4-356a9ba3528f.png)
真っ青です。サルゲッチュの深海ステージでこんな色合いのマップがありました。
病院の手術室は医者の色残像を防ぐため背景色が赤の補色の青緑になっています。
そういうシーンを演出するために使えるかと思われます。
余談ですが、仮面ライダーアマゾンズのシーンは全体的に青みがかっています。
詳しくは検索してください。ああいった表現もColorizeで表現可能かと思います。**(グロ注意)**
（そうか、アマゾンズが青みがかった画面だったのは血の色を際立たせるためだったのか）

###Bloom tintとの関係性
前述したBloom tintと組み合わせるとどうなるか調べました。
上述の青Colorizeをリファレンスとして、いくつかエフェクト差し替えを試します。
まず上の画像は Bloomなし、Colorize青(0,150,255,255) でした。
次に Bloomあり白(255,255,255)、Colorize青(0,150,255,255) です。
![bandicam 2019-06-24 17-23-20-562.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/7ee5b3c7-e145-e6fb-c442-112716e81898.png)
ぼんやりと青く発光しました。深海感は変わりません。
Bloom tintの項で記した通り、**ColorizeはBloomの色ごと着色してしまいます。**
使い所に注意しましょう。

次に Bloomあり青(0,150,255)、 Colorize青(0,150,255,255)です。
![bandicam 2019-06-24 17-26-01-171.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/ad577988-c3a5-c53d-08fe-0fc70351547f.png)
青発光に青を重ねているので、当然ながら青が深くなります。

最後に Bloomあり青(0,150,255)、 Colorizeなしです。
![bandicam 2019-06-24 17-27-24-825.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/c9fcd973-4502-5a70-4563-b1ff7581b0fc.png)
全体が色を取り戻し、青だけが少し発光しています。
恐らく一番バランスが取れていて汎用性が高いのは最後の画像だと思います。
水中など、**色は乗せるが全て上書きするほどではないシーンなどではBloom tint**を
夕焼けなど、**環境光丸ごと色を変えて、全て上書きするシーンではColorize**を
選択するとちょうどよく表現できます。

##Vignette
ビネットです。見ての通り公式PPSv1でもVignetteです。
![SnapCrab_2019-06-24_17-43-03_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/faf22eff-ae26-b3e1-ea46-f241e99e7ff8.png)
削減された機能としては、中心座標の設定、円形度合いの変更、テクスチャモードです。
それ以外は本当にただのビネットです。
![bandicam 2019-06-24 17-48-20-861.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/3c3c124e-c274-fd38-d828-c9fe461b8943.png)

強いていうなら中心座標の変更が効かなくなったところが不便です。
例えば[株式会社アンビリアル](https://unbereal.co.jp/)さんのゲームで ARTI FIGHT というバトルゲームがありましたが、
左右に曲がるときに片方にビネットを寄せて、
酔いを軽減させつつ進行方向の視界を狭めないという調整をしていましたが、
そのようなトリッキーな演出が不可能になりました。
使うことは稀かと思いますが、いざというときに使えないと不便なので注意してください。

https://www.youtube.com/watch?v=1PfTpoeTmYE
<iframe width="560" height="315" src="https://www.youtube.com/embed/1PfTpoeTmYE" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

##Brightness / Contrast
輝度とコントラストです。公式PPSv1ではColor Gradingの一部機能に相当します。
Colorize同様シンプルになっています。
![SnapCrab_2019-06-24_17-58-03_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/919c82fe-0b0d-0a05-7283-4d93d0bcfa94.png)

この項目はあまり説明は必要ないと思います。
コントラストを上げればギラギラした絵に、
輝度を上げれば眩しくなります。
この画像はコントラストを1、輝度を-0.6にしました。わかりやすいエフェクトですね。
![bandicam 2019-06-24 18-03-56-141.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/ecd2b90b-639b-6932-7df7-f2a7a0d70fae.png)

##負荷計算
これはエフェクトではありませんが、プロファイルに記載されている情報なのでここに書きます。
![SnapCrab_2019-06-24_18-17-14_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/9ae0a21b-2f1b-585f-7d7e-afc8c05209aa.png)
どのエフェクトがどの環境で、どれだけの処理時間を掛ける予定かの秒数です。
上がWorst case（一番酷いとき）
下がGeneral case（ふつう）です。
負荷軽減カスタムをするときはこの窓を見ながら行っていくといいでしょう。
ただ、そもそもSleek Render自体が軽量なので、あまり気にしないでも大丈夫かと思います。

#動作環境について
全てのエフェクトの説明が終わったので、Sleek Renderの動作する環境について少し記します。
冒頭で記した通り、公式発表で**どのVR形式もサポートしていない**とされていましたが、
**少なくともOculusRift(SteamVR),OculusGo,OculusQuestでは正常に動作しました。**
Go,Questはマルチパス環境で動作しました。シングルパスステレオは正確には検証していません。
負荷軽減テストで一瞬シングルパスにしたところ、Bloomは起動しているように見えたので、
恐らくシングルパスでも動きます。
このアセットを使っていたチームメイトがVive担当なので、多分Viveでも動きます。

サポートしていないと公言しているのは
”動作確認もしてないし、問題があったときにはサポートしないよ”という意味で、
”一切動作しないよ”という意味ではなさそうです。
また、アセット作者は[フォーラムのスレッドでQuestに興味を示している](https://forum.unity.com/threads/sleek-render-lightning-fast-mobile-post-processing-effects.502181/page-5#post-4353295)ので、
将来的に正式サポートが始まるかもしれません。

#まとめ
有料アセットの情報をここまで流してしまうのは大丈夫なんでしょうか。
アセットストア規約とかで刺されなければいいんですが、、
負荷は軽減させたいけど見栄えは落としたくない人や、
SteamVRで動いていたゲームをOculusQuestに移植する人などの
参考になれば嬉しいです。

##あとがき
冒頭でも記しましたがこの記事は[リリース済みSteamVRゲームをQuestに移植した話](https://qiita.com/GONBEEE_project/items/590405a1f514559712c5)の続編になります。
続編と言っても内容は独立していますが、この記事も合わせて読むとSleek Renderの良さが分かると思います。

何か追記してほしい情報や質問があれば、
Qiitaのコメント欄か [@GONBEEE_project](https://twitter.com/GONBEEE_project) までリプDMでご連絡ください。

最後までお付き合いいただきありがとうございました。