Search Unity

ユニバーサルレンダーパイプラインで実現する、美しくスケーラブルで高パフォーマンスなグラフィックス

, 2月 10, 2020

ユニバーサルレンダーパイプラインは、コンテンツ制作用のアーティスト向けツールを網羅した、すぐに使える便利なソリューションです。Unity 対応プラットフォーム全体をターゲットにして、業界最高レベルのビジュアルクオリティーとパフォーマンスを備えたゲームを制作するなら、このレンダリングパイプラインをぜひご利用ください。ユニバーサルレンダーパイプラインのメリットについては、こちらのブログ記事をご覧ください。このブログ記事では、バーティカルスライスとして制作された『Boat Attack』のデモで、ユニバーサルレンダーパイプラインがどのように使われたのかを詳しく解説しています。

最初に『Boat Attack』のデモを制作したのは、ユニバーサルレンダーパイプライン(当時は軽量レンダーパイプラインと呼ばれていました)の検証とテストを行うためでした。また、開発プロセスの一環としてバーティカルスライスを制作したのには、機能開発に現実世界の制作プロセスを応用してみるという意味合いもありました。

『Boat Attack』のデモは、当初制作されたものから、かなり改善されています。現在では、C# Job SystemBurst コンパイラーシェーダーグラフInput System などの最新の Unity 機能とともに、ユニバーサルレンダーパイプラインの新しいグラフィック機能が使われています。

今すぐ『Boat Attack』のデモをダウンロードし、Unity 2019.3 で実際に体験してみてください。

デモ

『Boat Attack』のデモは、ボートレースゲームの形をとったコンパクトなバーティカルスライスです。実際にプレイ可能で、Unity の最新機能を最大限活用するよう頻繁に調整を行っています。

このデモは、ミッドレンジからハイエンドのモバイルデバイス、現行世代のあらゆるコンソール、スタンドアロンアプリなど、幅広いプラットフォームで快適に動作するように設計されています。Unite Copenhagen 2019 では、iPhone 7 から PlayStation 4 まで、さまざまなデバイスで『Boat Attack』のデモをライブで披露しました。

デモを使用するには、Unity 2019.3 の最新バージョンをインストールし、GitHub からプロジェクトを入手してください(必ず README ファイルで使い方に関する指示を確認してください)。

シェーダーグラフ

シェーダーグラフは、アーティストにとって使いやすい、シェーダーを作成するためのインターフェースです。これは、テクニカルアーティスト向けの便利なプロトタイプ作成ツールです。『Boat Attack』のデモでは、さまざまな独自のシェーディングエフェクトを生み出すためにシェーダーグラフが使われています。

シェーダーグラフを使用すれば優れたシェーディングエフェクトを作成できるだけでなく、作成したエフェクトを多くのバージョンのライトウェイトレンダーパイプラインやユニバーサルレンダーパイプラインで簡単に維持できます。

 

『Boat Attack』の崖のシェーダーは、メッシュデータで実現できるエフェクトの例です。データはシェーダーグラフのメッシュから簡単に取得できます。デモではメッシュの法線ベクトルを使用して崖の上向きの平らな面に草を描画し、メッシュのワールド空間の高さを使用して海水面に近い崖や岩に草を生やさないようにしています。

左から右に向かって:Y 高さマスク、Y 法線マスク、リマップされた高さ + 法線マスク、完成版のシェーダー

植生生成シェーディング

 

『Boat Attack』の植生生成は当初カスタムの頂点/フラグメントシェーダーで行っていましたが、この方法はレンダーパイプラインが開発初期段階でコードが頻繁に変更される状況下では、維持するのが大変でした。シェーダーグラフでシェーダーを作り直したことで、簡単にアップグレードできるシェーダーグラフをうまく利用できるようになります。

このシェーダーグラフエフェクトは、Crytek 社の Tiago Sousa 氏が実装した、頂点色をフル活用して頂点ディスプレイスメントを通じて風のアニメーションを制御するしくみに基づいています。『Boat Attack』ではサブグラフを作成して、そこに風のエフェクトを計算するために必要なすべてのノードを格納しました。このサブグラフには、ネストされたサブグラフが格納されています。サブグラフは、繰り返し演算を実行するユーティリティグラフのコレクションです。

 

個々の頂点アニメーションとそのマスク。左から右に向かって:原点への距離に基づくメインのしなり、頂点色の赤(R)チャンネルに基づく葉の周縁、頂点色の青(B)に基づいて位相オフセット用に頂点色の緑(G)チャンネルを使用した枝

リアルな植生を作成するためのもう 1 つ大きな要素が、サブサーフェススキャッタリング(SSS)です。SSS は、現時点ではユニバーサルレンダーパイプラインでは利用できません。とはいえ、シェーダーグラフのカスタム関数ノードを使用してユニバーサルレンダーパイプラインからライティング情報を取得することで、独自の SSS 風エフェクトを創出できます。

ノードのレイアウト。頂点色の緑(葉の位相)とアルベドテクスチャーマップから作成された SSS マスク

カスタム関数ノードにより、自由な創作の幅が広がります。カスタムレンダリングの手法については、こちらの記事が参考になります。または、『Boat Attack』のリポジトリにあるノード用のコードを取得して、自作のカスタムライティングのアイデアをお試しいただいてもかまいません。

左から右に向かって:SSS なし、SSS のみ、完成版のシェーダー

ボートのカスタム化

 

ボートには色のバリエーションが複数必要でした。Substance Painter で模様の塗装の形にあわせたマスクを 2 つ描画して、メタリック(赤)、スムースネス(緑)、塗装 1(青)、塗装 2(アルファ)を含むパック済みテクスチャーに格納しました。シェーダーグラフ経由でマスクを使用することで、マスクされたこれらの領域にカラーリングを選択的に適用できます。

ボートのカラーリング方法の概要。オーバーレイブレンディングを使用すると、ベースのアルベドマップに繊細なカラーリングを適用可能。

親の RaceBoats グラフで使いやすいようにサブグラフにまとめられたシェーダーグラフ内のノードのレイアウト

 

『Boat Attack』では、昼と夜のサイクルが完全に再現されます。これをよりリアルに見せるため、レベル全体にわたって建物の窓にシェーダーグラフを作成しました。シェーダーグラフによって、夕暮れ時になると窓に明かりが灯り、夜明けとともに明かりが消えます。

これを実現するために、昼/夜の値にマッピングされたシンプルな発光テクスチャーを使用しました。オブジェクトの位置を使って順番を若干ランダム化するエフェクトを追加することで、家々に異なるタイミングで明かりが灯るようにしました。

ランダムな発光を実現するノードマップ

 

『Boat Attack』に変化するライティングを追加したので、シンプルなハイダイナミックレンジイメージング(HDRI)スカイボックスではもの足りなくなりました。シーン内のライティングで雲を動的に照らす必要があります。

しかし、ふわふわの大きな雲のリアルタイムレンダリングは要求が厳しくなります。モバイルハードウェアで実行する必要があるなら、なおさらです。雲をさまざまな角度から見せる必要はないので、パフォーマンスを節約するためにテクスチャーを持つカードを使うことにしました。

現在雲のレンダリングに使用しているグラフ全体

シェーダーグラフは外観のプロトタイピングにおいて、重要な役割を果たしました。Houdini から雲のボリューメトリックデータをいくつかベイクして、シェーダーグラフで詳細にカスタマイズしたライティングを作成しました。これらの雲はまだ作成途上ですが、ノードベースのエディターでさまざまなサーフェスを作り出せることを証明しています。

API からのレンダリングでシームレスな平面反射を表現

Unity がスクリプタブルレンダーパイプラインで目指しているのは、レンダリングコードをブラックボックス化することではなく、ユーザーがレンダリングコードをカスタマイズできるようにすることです。Unity は、既存のレンダリングコードを単にオープン化することよりも、新しい API やハードウェアを念頭に置いた Unity のレンダリング技術を推進してきました。

ユニバーサルレンダーパイプラインに標準搭載されているレンダリング機能は、独自の C# コードで拡張できます。以下の 4 つのフックが公開されています。

  • RenderPipelineManager.beginFrameRendering
  • RenderPipelineManager.beginCameraRendering
  • RenderPipelineManager.endCameraRendering
  • RenderPipelineManager.endFrameRendering

これらのフックを使えば、シーンや特定のカメラをレンダリングする前に、簡単に自作のコードを実行できます。『Boat Attack』では、これらのフックを使って、メインフレームがレンダリングされる前にシーンをテクスチャー内にレンダリングすることで平面反射を実装しています。

これはサブスクライブ先のコールバックで、OnDisable では逆にサブスクライブを解除します。

これは平面反射スクリプトのエントリポイントです。このコードで、ユニバーサルレンダーパイプラインがカメラをレンダリングしようとするたびにカスタムメソッドを呼び出すことができます。呼び出すのは、ExecutePlanarReflections メソッドです。

コールバックに [beginCameraRendering] を使用しているので、メソッドは [ScriptableRenderContext] と [Camera] をパラメーターとして持つ必要があります。このデータはコールバックと一緒に受け渡され、レンダリングされるカメラを知らせてくれます。

このコードは平面反射を実装するために通常使われるコードとほぼ同じで、カメラと行列の処理を行います。唯一の違いは、ユニバーサルレンダーパイプラインにはカメラをレンダリングするための新しい API が用意されていることです。

平面反射を実装するためのメソッド全体は、以下のとおりです。

ここでは新しい [UniversalRenderPipeline.RenderSingleCamera()] メソッドを使って所定のカメラをレンダリングしています。この場合、カメラは平面反射カメラです。

このカメラはテクスチャー([Camera.targetTexture] を使用して設定)にレンダリングされるので、この後のレンダリングで水のシェーディングに使用できるレンダーテクスチャーをこの時点で入手します。PlanarReflection のスクリプト全文は、GitHub のページで確認してください。

平面反射の合成。左から右に向かって:平面反射カメラの生の出力、フレネルを暗くして法線をオフセット、完成版の水のシェーダー、平面反射がない水のシェーダー

これらのコールバックは、ここではレンダリングを呼び出すために使用されていますが、その他の用途もあります。たとえば、平面反射カメラのシャドウを無効にしたり、カメラに使用するレンダラーを選んだりするためにも使用できます。シーン内やプレハブ内の動作をハードコーディングするよりも、API を使う方が、より複雑な動作をより細かく制御できます。

カスタムレンダーパスの挿入による特殊エフェクト

ユニバーサルレンダーパイプラインでは、ScriptableRenderPass に基づいてレンダリングが行われます。ScriptableRenderPass は、レンダリング対象とレンダリング方法に関する命令セットです。ScriptableRenderPass の多くはまとめてキューに追加され、ScriptableRenderer と呼ばれるものを形成します。

ユニバーサルレンダーパイプラインのもう 1 つの要素が、ScriptableRendererFeature です。ScriptableRendererFeature は基本的にカスタム ScriptableRenderPass のデータコンテナで、多数のパスをアタッチされている各種データとともに格納できます。

ForwardRenderer と 2DRenderer という 2 つの ScriptableRenderer が最初から付属しています。ForwardRenderer は ScriptableRendererFeature の挿入をサポートします。

ScriptableRendererFeature をより簡単に作成できるように、Unity は、テンプレートファイルから作成する機能を追加しました(C# の MonoBehaviour スクリプトの場合と非常に似ています)。Project ビューで右クリックして [Create/Rendering/Universal Pipeline/Renderer Feature] を選択するだけで、元になるテンプレートファイルが生成されます。生成されたテンプレートで、ForwardRendererData アセットの「Render Feature」リストに ScriptableRendererFeature を追加できます。

『Boat Attack』のデモでは、ScriptableRendererFeatures を使って水のレンダリング用に 2 つのレンダリングパスを追加しました。1 つはコースティクス用で、もう 1 つは WaterEffects と呼ばれるものです。

コースティクス

 

Caustics ScriptableRendererFeature により、シーンの不透明なパスと透明なパスの間にカスタムコースティクスシェーダーをレンダリングするパスが追加されます。これを実現するため、水に沿って大型のクアッドをレンダリングして空中のピクセルがレンダリングされないようにします。クアッドはカメラを追いかけますが水の高さにスナップされ、シェーダーが不透明なパスから画面に写っているものの上から付加的にレンダリングされます。

コースティクスのレンダーパスの合成。左から右に向かって:深度テクスチャー、深度に基づくワールド空間位置の再構成、ワールド空間位置でマッピングされたコースティクステクスチャー、不透明なパスとの最終的なブレンド

[CommandBuffer.DrawMesh] を使用すると、クアッドを描画し、(水とカメラの座標に基づいて)メッシュの位置を決めるための行列を指定して、コースティクスマテリアルを設定することができます。このコードは次のようになります。

水のエフェクト

 

WaterFXPass の動作を説明するためのスプリットビュー。左側は最終的なレンダリング、右側は水上のパスの結果のみを表示しているデバッグビュー

WaterFXPass はもう少し複雑です。このエフェクトの目的は、波や泡の発生など、オブジェクトによる水への影響を生み出すことです。これを実現するために、テクスチャーの各チャンネルにそれぞれ異なる情報を書き込むことができるカスタムシェーダーを使って、オフスクリーンのレンダーテクスチャーに特定のオブジェクトをレンダリングします。泡のマスクは赤のチャンネルに、法線オフセットの X と Z は緑と青のチャンネルに、最後に水のディスプレイスメントはアルファチャンネルに書き込まれます。

WaterFXPass の合成。左から右に向かって:最終的な出力、ワールド空間法線の作成に使用される緑と青のチャンネル、泡のマスクに使用される赤のチャンネル、水のディスプレイスメントの作成に使用されるアルファチャンネル(赤 = 正、黒 = 一定、青 = 負)

まずはレンダリング先となるテクスチャーが必要なので、半解像度で作成します。次に、WaterFX というシェーダーパスを持つ透明オブジェクト用にフィルターを作成します。その後、[ScriptableRenderContext.DrawRenderers] を使用してシーンにオブジェクトをレンダリングします。最終的なコードは次のようになります。

これらの ScriptableRenderPass は両方とも 1 つの ScriptableRendererFeature 内に存在します。この機能には [Create()] 関数が含まれており、これを使用すると、リソースを設定したり、設定を UI から渡したりすることができます。これらは水をレンダリングする際は常に一緒に使用されるため、1 つの機能で ForwardRendererData に追加できます。コード全体は、GitHub で確認できます。

今後の計画

Unity は、2019.4 LTS を含む Unity 2019 のサイクルを通じて引き続きこのプロジェクトを更新していきます。Unity 2020.1 以後は、プロジェクトが動作するように保持するつもりですが、新しい機能は追加しない予定です。

今後予定されている改善点の一部を紹介します。

  • 昼/夜サイクルを完成させる(カスタム化の必要性を低減するためにユニバーサルレンダーパイプラインにより多くの機能を統合する必要があります)
  • 水の UX/UI を洗練する
  • Imposter を実装する
  • コードのクリーンアップとパフォーマンスの微調整を継続する

役立つリンク

GitHub の『Boat Attack』リポジトリ

2019.3 プロジェクト全体へのリンク(GitHub を利用したくない場合)

ユニバーサルレンダーパイプラインのマニュアル

ユニバーサルレンダーパイプラインと HD レンダーパイプライン

ユニバーサルレンダーパイプライン(UniversalRP)は HD レンダーパイプライン(HDRP)の代替となるものではなく、HDRP の機能を含むものでもありません。

ユニバーサルレンダーパイプラインは、今後 Unity におけるデフォルトのレンダーパイプラインになる予定です。「1 回の開発でどこにでもデプロイ」を合言葉に、高い柔軟性と拡張性を備えたユニバーサルレンダーパイプラインは、組み込みのレンダーパイプラインよりも高いパフォーマンスを発揮し、さまざまなプラットフォームに拡張可能です。また、グラフィックスの品質も優れています。

HDRP は最先端のグラフィックスをハイエンドのプラットフォームで実現します。HDRP は、ハイエンドなハードウェア向けのグラフィックスに重点を置いた、高パフォーマンスで強力な、忠実度の高いビジュアルを目標とするプロジェクトに最適です。

使用するレンダリングパイプラインは、プロジェクトの機能やプラットフォームの要件に応じて選択ください。

UniversalRP を使ってみよう

製品版のすべての機能と優れたパフォーマンスを、すぐにご利用いただけます。アップグレードツールを使用してプロジェクトをアップグレードするか、Unity Hub からユニバーサルプロジェクトテンプレートを使用して新しいプロジェクトを開始してください。

ユニバーサルレンダーパイプラインに関するフォーラムに、ぜひフィードバックをお寄せください!

31 replies on “ユニバーサルレンダーパイプラインで実現する、美しくスケーラブルで高パフォーマンスなグラフィックス”

Ask a question,
How the cloud’s normal map is rendered in the project,in houdini what should I do

This is a nice post. First thing I tried was to see how well the water system works in VR. Looking forward to when you have it working – It looks promising.

Very good progress, this URP.
I’m missing:
– realtime GI
– volumetric fog (from HDRP. I know it’s expensive)
– lens flares…?

Also I couldn’t get any great performance with URP on HoloLens2 for some reason (<50fps in release mode for a few cubes on low quality).

What about Lens Flares? Are you planning to implement them? They are available in standard built-in render.

Frankly the biggest hold back for me is waiting on various assets to start supporting URP, most don’t want to touch it because they can’t trust it isn’t going to change, or bugs will hinder progress causing wasted time etc….

It’s work in progrses

Frankly the biggest hold back for me is waiting on various assets to start supporting URP, most don’t want to touch it because they can’t trust it isn’t going to change, or bugs will hinder progress causing wasted time etc….

It’s work in progrses

This is nice and all, but why not integrate things like Planar Reflection and Water into the Render Pipeline itself, or at least have them as an optional “extras” package?

Great post, but I would argue that URP isnt really ready to use unless you dont really care about control or quality.

Until breaking changes and bugs stop happening, and until it performs well on XR, and until custom post processing and camera stacking is supported in a way that makes sense and doesnt make custom FX REALLY difficult to do, its not really a ready to use solution for anyone serious about making games.

Loving the work so far, but you guys need to stop flaunting your work constantly as ready. Its not ready, its very much a work in progress as evidenced by pretty much everything anybody working on URP has ever said publically.

The Demo Island scene always crashes for me in 2019.3.0f6 and 2020.1.0a22 – both with a fresh git clone and downloading the above zip file. I tried that on multiple different machines in different locations. Also, it throws hundreds of exceptions on project launch (before trying to open that scene).

(Case 1218663) [Editor Crash][Boat Attack Demo] Editor crashes on selecting “open demo_island”
(Case 1218678) [Editor][Boat Attack Demo] Errors in the console on clean project
(Case 1218693) [Editor] Boat Demo crashes on start (from a different machine)

My main complaint is that URP is not getting great support for XR. The boat attack demo mostly doesn’t render at all in XR if you pop a vr camera in the scene.

I have spent ages reporting bugs with URP for Oculus Quest and Go which are platforms that deserve to make the most of these performance improvements also!

Thanks for the post, it’s an interesting read from start to end!

I always wondered how caustics can be implemented in an efficient way. After reading you post, I finally know. It’s so simple! :)

I’m a big fan of LWRP/URP. The only major issue is: No grab pass. This really limits what you can do. Are there plans to address this?

Has there been any updates on when the standard pipeline will be deprecated? After 2020 LTS?

Not any time soon, the Standard Render Pipeline will stay for many years to come as far as I’m aware. I’m pretty sure they already talked about this in a couple previous posts

You’ve embeded One Drive documents in this post that don’t display, because they aren’t public.

Comments are closed.