こんにちは。タノシムスタジオ@渋谷オフィスでクライアントエンジニアをやっている飛田です。タノシムスタジオでは、クライアントサイドにUnityを採用して、ゲーム開発をしています。今回は、Unityの比較的新しい機能であるUniversal Render Pipelineについて、解説したいと思います。
はじめに
Unityは、2005年の登場から現在までシェアを拡大し続け、インディーズ、商用を問わず、また、多様なプラットフォームのゲーム開発に利用されるようになりました。その歴史の中で、Unity はアップデートされ続け、バージョンアップするごとに様々な機能が追加されてきました。
新機能をキャッチアップすることは、パフォーマンスの改善や、表現力の向上のために、非常に重要です。この記事では、Universal Render Pipelineを取り上げて、概要を解説するとともに、手を動かしながら、導入方法を学べるサンプルを提供することを目指しています。この記事では、とりあえず導入してみて、カメラスタッキングを試して見るところまでをゴールとしました。
なお、サンプルの内容は、以下の開発環境で検証しました。
- UnityHub 2.3.0 + Unity 2019.3.5f1
- UniversalRP 7.2.1
- Build Settings
- Platform: PC, Mac & Linux Standalone => Target Platform: Mac OS X
Universal Render Pipelineとは
まず、Universal Render Pipeline(URP)とは何なのかを、簡単に説明します。URPはScriptable Render Pipeline(SRP)の実装の一つなので、SRPとは何なのかを概説した後、改めてURPの位置づけや、URPを導入すると何ができるのかを説明します。
Scriptable Render Pipeline
Unity Technologies社は、オープンで拡張可能なレンダーパイプラインを、モジュールとして切り出し、開発者やアーティストに、それぞれのニーズに合ったレンダーパイプラインを作成する手段を提供するという戦略を打ち出しました。このレンダーパイプラインは、Scriptabe Render Pipelineと呼ばれ、ブラックボックス化されていた、従来のビルトインレンダーパイプラインとは、大きく異なります。
Scriptable Render Pipeline (SRP) は、一から自分でコードを書いて作成することも可能ですが、Unityは、Universal Render Pipeline (URP) とHigh Definition Render Pipeline (HDRP) という、2つの既存実装を提供しています。今回の主題であるURPについては、次節で解説します。HDRPについては、今回は軽く触れるにとどめますが、コンピュートシェーダーをサポートするプラットフォームをターゲットにした、物理ベースのライティングを利用するパイプラインです。Unity Technologies社は、この2つのどちらかをそのまま利用するか、必要に応じてカスタマイズを加え、独自のレンダーパイプラインを作成して、利用することを想定しています。
また、URP/HDRPを適用したプロジェクトでは、Shader Graph、Visual Effect Graphという新しい機能を利用することができます。Shader Graphは、シェーダーを視覚的に、構築する機能で、これによって、従来はプログラミングの領域であったシェーダーを、アーティストなどの他のメンバーが構築可能になります。Visual Effect Graphも同様に、従来のParticle Systemで作成していたようなビジュアルエフェクトを、グラフベースのGUIを使って制作できます。
Universal Render Pipline
URPはモバイルゲームからハイエンドコンソールゲームまでを対象にした、汎用的に利用可能なパイプラインです。様々なプラットフォームで、汎用的に利用可能なものとして、開発されており、従来のレンダーパイプラインよりも、クオリティが向上し、軽量化もされています。また、URPでは、拡張性のために、レンダラーという概念が導入されています。独自のレンダラーを実装し、使用するレンダラーを変更することで、レンダーパイプライン全体を構築することなく、異なるレンダリングストラテジーを用いることができます。
URPは、Unity2018.3で、Lightweight Render Pipeline (LWRP)という名称で、 preview版として公開され、その後、2019.3.0で現在の名称に変更され、正式版となりました。SRP関連のライブラリは、パッケージとして切り出されており、UnityのPackage Managerでインストールやアップデートができます。
URPを使ってみよう
ここからは、Unityを使って、実際にURPを利用したプロジェクトを作成し、簡単な例を通して、従来のレンダーパイプラインとの違いや、注意するべきことについて、述べていきたいと思います。
プロジェクトの準備
URPを利用するには、プロジェクトがURP用にセットアップされている必要があります。ここでは、新規プロジェクトを作成する場合の手順について解説し、少しだけ、既存プロジェクトをURP用の設定にする方法についても触れます。
また、後でURP7.2.0で追加されたカメラスタッキングの使用方法について述べるので、そのためのパッケージのアップデート手順を説明します。
URPプロジェクトの作成
既存のプロジェクトに、後からURPを適用することもできますが、新規のURPプロジェクトを作成する場合は、URP用のテンプレートを指定して、プロジェクトを作成するのが簡単です。
- UnityHubの「プロジェクト」タブから、新規作成ボタンの横の三角ボタンをクリックし、「Unity2019.3.5f1」を選択する
- テンプレートに「Universal Project Template」を選択し、プロジェクト名に適当なプロジェクト名を入力して、作成ボタンをクリックする
Unityが起動すると、あらかじめオブジェクトが配置された、サンプルシーンが見える状態になっているはずです。また、メニューからEdit > Project settingsと進んでProject settingsウインドウを開き、Graphicsタブを見てみると、Scriptable Render Pipelint Settingsに「UniversalRP-High Quality (UniversalRederPipline)」がセットされていることがわかります。
なお、既存プロジェクトに後からURPを適用する場合、Package ManagerでURPパッケージをインストールした後、Projectウインドウで右クリックし、コンテキストメニューからCreate > Rendering > Universal Render Pipeline > Pipeline Asset (Forward Renderer)と進んで、PipelineAssetを作成し、Project stettingsのScriptable Render Pipelint Settingsの項目に、そのAssetを設定するという手順が必要になります。
URPのアップデート
URP7.2.0からカメラスタッキングの機能が追加されました。この機能を利用するために、以下の手順で、Package Managerから、URPのバージョンアップを行います。
- メニューからWindow > Package Managerと進み、Package Managerウインドウを開く
- ウインドウ上部のプルダウンメニューで、「In Project」を選択し、インストール済みのパッケージのみを表示する
- ウインドウサブに表示されている一覧から、Universal RPを選択し、「Update to 7.2.1」ボタンをクリックする
Hierarchyビューで、「Main Camera」を選択し、Inspectorビューを見てみると、Cameraコンポーネントの一番下にStackという項目があるのが見えるはずです。
シェーダーとマテリアルの設定
URPを利用していると、URP用に書かれたシェーダーを使わないと、意図通りにレンダリングができない場合が多くあります。基本的なものは、URPパッケージに同梱されています。例えば、従来のStandardサーフェスシェーダーに対応する、もっとも基本的なシェーダーとして、Universal Render Pipepine/Litが用意されており、Particle用のシェーダーとしては、Universal Render Pipepine/Particles/Litなどがあります。また、URPでは、2D Lightという新機能を利用することができ、そのためにUniversal Render Pipepine/2D/Sprite-Lit-Defaultというシェーダーが用意されています。
以下は、URP用のLitシェーダーを適用したマテリアルをアタッチしたオブジェクトと、従来のStandardシェーダーを適用したマテリアルをアタッチしたオブジェクトの対比です。
はじめからURPプロジェクトして作成された場合は、デフォルトでシーンにオブジェクトを作成すると、デフォルトでURP用のシェーダーをセットしたマテリアルがアタッチされています。また、既存プロジェクトに後からURPを導入した場合は、メニューバーからEdit > Render Pipeline > Universal Render Pipeline > Upgrade Project Materials to UniversalRP Materials またはUpgrade Selected Materials to UniversalRP Materialsを選択することで、プロジェクト内のすべてのマテリアルまたは選択したマテリアルを、自動でURP用に変換することができます。
URPでカメラスタッキングを使ってみよう
前述しましたが、URP7.2.0でカメラスタッキングの機能が追加されました。ここでは、この機能を簡単に紹介します。
カメラスタックを設定する
ここでは、2つのオブジェクトを、それぞれ別のカメラで撮影し、カメラスタッキングを利用して、それぞれのカメラの映像を重ね合わせてみようと思います。まず、シーン上にMain CameraとOverlayCameraを設置し、Main CameraでCubeを撮影、OverlayCameraでSphereを撮影した状態にします。それから、Main Cameraでとった映像の上に、OverlayCameraで撮った映像を重ねます。
まずは、準備として以下の手順で、新規シーンの作成とレイヤーの追加をしましょう。
- Projectビューで右クリックし、コンテキストメニューからCreate > Sceneを選択し、新しいシーンを作成する
- 作成したシーンをダブルクリックして、そのシーンを表示する
- Unity Editorの右上にある、「Layers」というプルダウンメニューから「Edit Layers」をクリックする
- Inspectorビューに表示されたTags & Layersの設定で、User Layer 8の欄に、OverlayCameraと入力する
次に、カメラの追加と設定を行います。
- Hierarchyビューで、右クリックし、Cameraを選択して、新しいカメラを作成し、名前をOverlayCameraに変更する
- HierachyビューでOverlayCameraを選択した状態で、CameraコンポーネントのRenderTypeをOverlayにする
- Hierarchyビューで、Main Cameraを選択した状態で、InspectorビューからCameraコンポーネントの下部にあるStackという項目の+ボタンを押して、「OverlayCamera」を選択する
最後に、それぞれのカメラに映るオブジェクトを作成します。
- Hierarchyビューで、Main Cameraを選択した状態で、InspectorビューからCameraコンポーネントのCullingMaskをDefaultだけにチェックが入っているように変更する
- Hierarchyビューで、右クリックし、3D Object > Cubeと選択し、Cubeオブジェクトを作成する
- HierachyビューでOverlayCameraを選択した状態で、InspectorビューからCulingMaskをOverlayCameraだけにチェックが入っているように変更する
- Hierarchyビューで、右クリックし、3D Object > Sphereと選択し、Sphereオブジェクトを作成する
- Hierarchyビューで、Sphereを選択した状態で、InspectorビューからLayerを「8: OverlayCamera」にする
- OverlayCameraとSphereの位置を適当に変更する(OverlayCameraをx:-10,y:0, z:-10, Sphereをx:-10, y: 0, z:0とか)
さて、Gameビューを見ると、CubeとSphereが両方見えるようになっているはずです。また、InspectorビューでSphereの座標を色々変化させてみると、OverlayCameraで撮影しているSphereが、必ずCubeよりも前に見えるかと思います。
なお、RenderTypeがBaseのカメラがシーン上に複数ある場合は、どちらかしか表示されないので気をつけてください。ただし、BaseになっているカメラのOutput TextureにRenderTextureをセットしている場合は、そのカメラの映像はRenderTextureに描かれるので問題ありません。
C#スクリプトでカメラスタックを動的に変更する
カメラスタックはC#から動的に変更をすることができます。さきほど、作成したカメラスタッキングのサンプルシーンにさらに手を加えて、検証してみましょう。
- 以下に示すC#スクリプト(CameraStackController.cs)を作成します
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.Universal;
[RequireComponent(typeof(Camera))]
public class CameraStackController : MonoBehaviour
{
Camera baseCamera = null;
float elapsedTime = 0f;
void Start()
{
baseCamera = GetComponent<Camera>();
}
void Update()
{
var cameraData = baseCamera.GetUniversalAdditionalCameraData();
elapsedTime += Time.deltaTime;
if (elapsedTime > 5f)
{
if (cameraData.cameraStack.Count >= 1)
{
cameraData.cameraStack.Clear();
}
}
}
}
- Hierarchyビューで、Main Cameraを選択した状態で、InspectorビューでAdd Componentボタンをクリックし、CameraStackControllerを選択する
再生ボタンを押して、ゲームを起動しましょう。5秒後に、カメラスタックがクリアされるので、OverlayCameraで撮影しているSphereが見えなくなるはずです。
C#スクリプト内で
using UnityEngine.Rendering.Universal;
を記述するのを忘れないでください。GetUniversalAdditionalCameraData()メソッドが、その名前空間内のExtensionで定義されているためです。
おわりに
今回は、URPについて、第一弾として、利用可能な可能なシェーダーの従来との違いや、カメラスタッキング機能の利用方法について、簡単に説明しました。
URPに関するトピックは他にも色々あるのですが、現在、URPプロジェクトでポストプロセッシングを利用する方法や、Shader Graphについての記事を準備中です。お楽しみに!
参考URL
Scriptable Render Pipelineについて: https://docs.unity3d.com/Packages/com.unity.render-pipelines.core@8.0/manual/index.html
Universal Render Pipelineについて: https://blogs.unity3d.com/jp/2019/09/20/how-the-lightweight-render-pipeline-is-evolving/
URP用のビルトインシェーダーについて: https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@7.2/manual/upgrading-your-shaders.html
カメラスタッキングについて: https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/master/com.unity.render-pipelines.universal/Documentation~/camera-stacking.md