(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]


本ブログの運営者kan.kikuchiが個人で開発したゲームです!


描画に関する処理をC#で書けるSRP(Scriptable Render Pipeline)とは【Unity】【SRP】


このエントリーをはてなブックマークに追加



この記事でのバージョン
Unity 2018.2.14f1


はじめに

Unity関連でSRPというワードをちょこちょこ目にするようになったので、

どんなモノか軽く調べてみた系の記事です!


先に箇条書きでざっくりとまとめてみると以下のような感じ。

  • SRPとは描画に関する処理をC#で書けるようにしたもの
  • SRPは1から全部自作する事も可能だが、テンプレも用意されている
  • テンプレはローエンド(モバイルとか)用のLWRPハイエンド(PS4以上)用のHDRPの2種類
  • LWRPはSRPを使わない状態より軽いが、一部機能が使えない。
  • HDRPは高機能かつ高品質なので、負荷もそれなりに高い。
  • SRPを使うと今までのShaderをそのまま使う事は出来ない
  • SRPで使える標準的なShaderは用意されている(LWRP用とHDRP用が別々にある)
  • SRPを使うとSurface Shaderが使えない
  • SRPを使うとCameraのコールバックが効かない(ImageEffect等を実装しなおす必要がある)
  • 上記のような欠点があるので、既存プロジェクトをSRPに移行するのは大変
  • SRPはプレビュー版なので、今後大幅な仕様変更の可能性がある



Scriptable Render Pipelineとは

まずSRP(Scriptable Render Pipeline)とは描画関連の機能なのですが、

そもそもQualitySettings等で調整出来るとは言え、Unityの描画周りは基本ブラックボックスです。


f:id:kan_kikuchi:20181107091851j:plain


このブラックボックス部分、つまり今まで手を加えられなかった描画部分

プログラム(C#)で操作出来るようにしたのがSRPです。

ようは「SRPとは描画に関する処理をC#で書けるようにしたもの」という事です。


例えば、Opaque(不透明)なオブジェクトは描画面積を減らすため手前から奥へ 、

Transparent(半透明)なオブジェクトは描画が破綻しないように奥から手前へ

描画するというルールがUnityにはありますが、これは基本的に変えられません。

しかしこのルールをSRPを使えば変えられるという事です。


f:id:kan_kikuchi:20181107092158j:plain
f:id:kan_kikuchi:20181107092204j:plain
【CEDEC2018】Scriptable Render Pipelineを使ってみよう


LWRPとHDRP

「描画に関する処理をC#で書ける」と言っても、さすがに全てを自分で書くのは敷居が高いので、

UnityからSRPのテンプレートが2つ用意されています。


1つ目はモバイルなどのローエンド向けのLWRP(Lightweight Render Pipeline : 軽量パイプライン)です。

LWRPは名前の通りSRPを使っていない標準の状態(Unityビルドパイプライン)より軽く早いですが、

デフォルトであったハイエンド向けの重い処理を削っているので、

一部使えない処理があります。(詳しくは下記サイトの表を参照のこと)


f:id:kan_kikuchi:20181107114020j:plain


2つ目はハイエンド(PS4以上)向けのHDRP(High Definition Render Pipeline : 高品質パイプライン)です。

HDRPは名前の通り高機能かつ高品質なので、負荷もそれなりに高いです。


SRPの欠点

便利そうなSRPですが、もちろん欠点もあります。

まず1番影響が大きそうなのが、今までのShaderがそのままでは使えないという点です。


他にもCameraのコールバックが効かなかったり(ImageEffect等を実装しなおす必要がある)、

Surface Shaderが使えないといった欠点もあり、注意が必要です。


また、現状Preview版なので、今後仕様が大幅に変更される可能性もあります。


導入方法

なんとなくSRPの大枠が分かった所で、次は実際の使い方です。

新しいプロジェクトで始める際はUnityHubTemplateを使うと楽です。


f:id:kan_kikuchi:20181107174347j:plain


既存のプロジェクトで使いたい場合はPackageManagerからインストールできます。

(GitHubから取得する事も可能)


f:id:kan_kikuchi:20181106173729j:plain
f:id:kan_kikuchi:20181106173805j:plain


インストールが済んだら、ProjectのCreateからAssetを作成します。(今回はLWRP用)


f:id:kan_kikuchi:20181107174921j:plain


あとは作成したAssetをEdit -> Project Settings -> Graphicsにある

SRPのSettingsにドラッグ&ドロップすれば準備完了です。


f:id:kan_kikuchi:20181106174015j:plain
f:id:kan_kikuchi:20181106174022j:plain


試しにアセットストアで買ったマップアセットのサンプルシーンに試してみると、


f:id:kan_kikuchi:20181107173025j:plain

Hand-painted Island Pack | 3D Fantasy | Unity Asset Store



Shaderがほとんど機能してない状態になります。


f:id:kan_kikuchi:20181107173042j:plain


なので、SRPで使える標準的なShaderに変えていきます。

(LWRPとHDRPに分けて用意されている)


f:id:kan_kikuchi:20181107173138j:plain


先にSRPに対応したShaderに自動で置き換えてくれる機能を使い、

置き換え出来なかった所を手動で設定していく感じになります。


f:id:kan_kikuchi:20181106174903j:plain
f:id:kan_kikuchi:20181107173056j:plain


同様にTerrainもそのままでは描画されないので、

SRPに対応したShaderを使ったMaterialを設定する必要があります。


f:id:kan_kikuchi:20181107175811j:plain
f:id:kan_kikuchi:20181107173234j:plain


Terrainで設置したオブジェクトもRender ModeがVertex Litだと表示されないので変更しましょう。


f:id:kan_kikuchi:20181107173311j:plain
f:id:kan_kikuchi:20181107173352j:plain
f:id:kan_kikuchi:20181107173418j:plain


これでとりあえず見れる状態にはなります。


f:id:kan_kikuchi:20181107173439j:plain


あとは最初に作成したAssetファイルの設定を調整したり、


f:id:kan_kikuchi:20181107173511j:plain


シーンに設置したライトの調整やベイクのやり直しをすれば、だいたい元の感じに戻せます。


f:id:kan_kikuchi:20181109122130j:plain


描画部分のプログラム

さて「今まで手を加えられなかった描画部分をプログラム(C#)で操作出来るようにしたのがSRP」

と最初の方で言いましたが、実際にどこで操作してるのかと言えば、LWRPだと以下の辺り。


f:id:kan_kikuchi:20181109074217j:plain


処理を読み解いていく場合はRenderPipelineを継承したクラス(LWRPだとLightweightPipeline)のRender

というメソッドが実際の描画処理を記述している所なので、ここから始めると良いかも知れません。


f:id:kan_kikuchi:20181109074240j:plain


なお、テンプレートを使わず、1からSRPを実装したい場合は以下の記事が参考になりそうです。

おそらく、いきなりLWRPのコードを読んだり、改造したりするより、

こちらから始めた方が理解しやすそうです。





おわりに

とりあえず概要を理解しただけですが、自分ですぐに使う事はなさそうな機能でした。


しかし「描画周りが重くて如何ともし難い!」「めちゃめちゃハイクオリティなやつが作りたい!」

という場合にはお世話になるかもしれないので、

今から勉強しとくのも有りかも知れないと言った感じでした。