Universal Render Pipeline(URP)乗り換えハマりポイントまとめ
概要
Built-in Render PipelineからUniversal Render Pipeline(以下URP)への乗り換えでわかりにくかったところなどをまとめてみます
環境は、Unity2020.1.15f1 > Unity2020.2.3f1 + URP10.2.2です
インストール
とりあえずこちらのドキュメントに沿っていけばオッケーです
Installing the Universal Render Pipeline into an existing Project
ざっくり次のような感じです
- PostProcessing Stack v2を使ってたら削除
URPにほぼ同様の機能が内包されているので事前に消しておく - PacakgeManagerでURPをインストール
- 設定ファイルを作成
- Graphicsセッテイングで3.のファイルを指定
乗り換え
Unity組み込みシェーダーの置換
Upgrading your Shaders
かわりのシェーダーとマテリアルの変換コマンドが用意されています
OnRenderObject()内でCamera.current==nullになる
仕様のようです
RenderPipelineManager.beginCameraRenderingイベントでカメラを覚えておく方法で対応できます
Camera currentCamera;
void OnEnable()
{
RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
}
void OnDisable()
{
RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
}
void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
{
currentCamera = camera;
}
void OnRenderObject()
{
if ((currentCamera == null) || (currentCamera.cullingMask & (1 << gameObject.layer)) == 0)
{
return;
}
~処理~
}
OnPreCull(),OnPreRender(),OnPostRender()非サポート
カメラにアタッチされているコンポーネント用のイベントが呼ばれなくなりました
シビアなケースでなければ上記OnRenderObject()のケース同様、RenderPipelineManagerのイベントで代用出来そうです
OnRenderImage()非サポート
カメラアタッチイベントなのでOnRenderImage()もサポートされなくなったのですが簡単な代用方法がなさそうです
Render Featureという自作のレンダリングパスを追加する機能があるので、これを利用するのがよさそうです
カメラを重ねる方法が変更
カメラの絵を重ねて描画する方法が変わっています
Built-in Render PipelineではカメラのCleaflags=Depth Only/Don't ClearにしてDepthの数値で処理順を調整して重ねていましたが、これらのパラメータがインスペクタ上に表示されなくなり設定出来なくなっています
URPではかわりにCamera Stacking機能を使います
上になるカメラのRenderTypeをOverlayにして
下になるカメラ(RenderTypeはBase)のStackに追加します
これで重ねて描画されます
Stackには複数登録でき、このリストの上から順に処理されます
いままでのDepth管理だと重なり順がわかりづらかったのでこれはいいですね
DepthバッファのクリアはOverlayにしたカメラのRendering > ClearDepthで指定できます
Shader乗り換え
UnityCG.cginc > Core.hlsl
UnityCG.cgincの代わりにCore.hlslをincludeします
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
CGPROGRAM > HLSLPROGRAM
CGPROGRAM / ENDCG
ではなくHLSLPROGRAM / ENDHLSL
を使うのが推奨されています
そもそもこの違いは、HLSLSupport.cginc、UnityShaderVariables.cgincが自動的にincludeされるかどうかだけのようです(前者だとされる)
これらのファイルで定義されている関数がURPの定義と衝突することがあるのでHLSLPROGRAM
推奨とのことです
NOTE: HLSL language is the preferred language for URP shaders.
NOTE: URP supports the CG language. If you add the CGPROGRAM/ENDCGPROGRAM block in a shader, Unity includes shaders from the Built-in Render Pipeline library automatically. If you include shaders from the SRP shader library, some SRP shader macros and functions might conflict with the Built-in Render Pipeline shader functions. Shaders with the CGPROGRAM block are not SRP Batcher compatible.
ビルドイン関数名変更
Core.hlslでは、ビルトイン関数がなくなったり名前が変わっていたりします
UnityObjectToClipPos()
がないのがよくひっかかるところかと思います
URPの座標系変換関数は次のファイルで定義されています(Core.hlsl経由でincludeされます)
Packages/com.unity.render-pipelines.universal/ShaderLibrary/SpaceTransforms.hlsl
float3 TransformObjectToWorld(float3 positionOS)
float3 TransformWorldToObject(float3 positionWS)
float3 TransformWorldToView(float3 positionWS)
float4 TransformObjectToHClip(float3 positionOS)
など
UnityObjectToClipPos()
のかわりはTransformObjectToHClip()
になります
とは言いつつ結構そのまま動く
手元の環境では特になにも書き換えなくてもそのまま動くシェーダーも結構多くありました
(ライティングまわりを全然触っていなかったからかな、という気もします)
乗り換え作業としては、エラーが出たところだけHLSLPROGRAM,Core.hlsl形式に書き換えていくというのも全然ありだと思います
機能比較表
公式にBuilt-in Render Pipelineとの比較表が公開されています
上記以外にもいろいろあるので乗り換えの際には一度目を通してみるのをおすすめします
個人的にはProjector非対応なのが痛いです
そのうち自前実装しなくちゃいけなくなりそうです
参考
Discussion