レンダーループとは、1 つのフレーム内で行われるすべてのレンダリング操作を意味します。このページでは、Unity のスクリプタブルレンダーパイプラインに基づいたカスタムレンダーパイプラインで、シンプルなレンダーループを作成する方法を説明します。
このページのコード例は、スクリプタブルレンダーパイプラインを使用する際の基本原則を示しています。この情報は、独自のカスタムスクリプタブルレンダーパイプラインを構築する際や、Unity にあらかじめ用意されているスクリプタブルレンダーパイプラインがどのように動作するかを理解するために利用できます。
レンダーループのコードを書き始める前に、プロジェクトの準備をする必要があります。
その手順は以下の通りです。
スクリプタブルレンダーパイプラインでは、LightMode
パスタグを使用して、ジオメトリの描画方法を決定します。パスタグの詳細については、ShaderLab: タグをパスに割り当てる を参照してください。
このタスクでは、LightMode パスタグ ExampleLightModeTag
によって、非常にシンプルな unlit シェーダーオブジェクトを作成する方法を説明します。
// これは、カスタムのスクリプタブルレンダーパイプラインと互換性のある単純な unlit シェーダーオブジェクトを定義します。
// ハードコードされた色を適用し、LightMode パスタグの使用法を示します。
// SRP バッチャーとは互換性がありません。
Shader "Examples/SimpleUnlitColor"
{
SubShader
{
Pass
{
// LightMode パスタグの値は、ScriptableRenderContext.DrawRenderers の ShaderTagId と一致する必要があります。
Tags { "LightMode" = "ExampleLightModeTag"}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
float4x4 unity_MatrixVP;
float4x4 unity_ObjectToWorld;
struct Attributes
{
float4 positionOS : POSITION;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
};
Varyings vert (Attributes IN)
{
Varyings OUT;
float4 worldPos = mul(unity_ObjectToWorld, IN.positionOS);
OUT.positionCS = mul(unity_MatrixVP, worldPos);
return OUT;
}
float4 frag (Varyings IN) : SV_TARGET
{
return float4(0.5,1,0.5,1);
}
ENDHLSL
}
}
}
レンダーループが動作することをテストするには、レンダリングするものを作成する必要があります。ここでは、前のタスクで作成した SRP 対応シェーダーを使うゲームオブジェクトをシーンに配置する方法を説明します。
準備の最終段階では、カスタム SRP に必要な基本的なソースファイルを作成し、Unity にカスタム SRP を使ったレンダリングを開始するように指示します。
RenderPipeline
を継承したクラスと互換性のあるレンダーパイプラインアセットを作成します。単純なレンダーループの基本的な操作は次のとおりです。
消去とは、最後のフレームで描画されたものを取り除くことです。レンダリングターゲットは通常スクリーンですが、テクスチャにレンダリングして「ピクチャーインピクチャー」効果を出すこともできます。これらの例では、Unity のデフォルト動作であるスクリーンへのレンダリング方法を示しています。
スクリプタブルレンダーパイプラインでレンダーターゲットを消去するには、以下を行います。
CommandBuffer
を Clear
コマンドで設定します。CommandBuffer
を ScriptableRenderContext
のコマンドキューに加えます。これを行うには、ScriptableRenderContext.ExecuteCommandBuffer を呼び出します。ScriptableRenderContext
のコマンドキューを実行するように指示します。これを行うには、ScriptableRenderContext.Submit を呼び出します。他のスクリプタブルレンダーパイプラインの操作と同様に、このコードのエントリーポイントとして、RenderPipeline.Render メソッドを使用します。以下のサンプルコードは、その方法を示しています。
/*
これは、カスタムのスクリプタブルレンダーパイプラインの簡略化された例です。
基本的なレンダーループがどのように機能するかを示しています。
最も効率的なランタイムパフォーマンスというよりは、最も明確なワークフローを示しています。
*/
using UnityEngine;
using UnityEngine.Rendering;
public class ExampleRenderPipeline : RenderPipeline {
public ExampleRenderPipeline() {
}
protected override void Render (ScriptableRenderContext context, Camera[] cameras) {
// 現在のレンダーターゲットを消去するコマンドを作成してスケジューリングします
var cmd = new CommandBuffer();
cmd.ClearRenderTarget(true, true, Color.black);
context.ExecuteCommandBuffer(cmd);
cmd.Release();
// スケジュールされたすべてのコマンドを実行するようにグラフィックス API に指示します
context.Submit();
}
}
カリングとは、カメラに映らないジオメトリをフィルタリングする処理です。
スクリプタブルレンダーパイプラインでカリングを行うには、以下を行います。
ScriptableCullingParameters
構造体の値を手動で更新します。CullingResults
構造体に格納します。このサンプルコードは、上の例を拡張したもので、レンダーターゲットをクリアしてからカリング操作を行う方法を示しています。
/*
これは、カスタムのスクリプタブルレンダーパイプラインの簡略化された例です。
基本的なレンダーループがどのように機能するかを示しています。
最も効率的なランタイムパフォーマンスというよりは、最も明確なワークフローを示しています。
*/
using UnityEngine;
using UnityEngine.Rendering;
public class ExampleRenderPipeline : RenderPipeline {
public ExampleRenderPipeline() {
}
protected override void Render (ScriptableRenderContext context, Camera[] cameras) {
// コマンドを作成してスケジューリングし、現在のレンダーターゲットを消去します。
var cmd = new CommandBuffer();
cmd.ClearRenderTarget(true, true, Color.black);
context.ExecuteCommandBuffer(cmd);
cmd.Release();
// すべてのカメラに繰り返します
foreach (Camera camera in cameras)
{
// 使用しているカメラからカリングパラメーターを取得します。
camera.TryGetCullingParameters(out var cullingParameters);
// カリングパラメーターを使ってカリング操作を行い、結果を保存します。
var cullingResults = context.Cull(ref cullingParameters);
}
// すべてのスケジュールされたコマンドを行うよう、グラフィックス API に指示します。
context.Submit();
}
}
描画とは、指定した設定で指定した 1 組のジオメトリを描画するようにグラフィックス API に指示するプロセスです。
SRP で描画するには、以下を行います。
CullingResults
構造体に格納します。このサンプルコードでは、上の例を基に、レンダーターゲットの消去、カリング操作の実行、その結果のジオメトリの描画を行います。
/*
これは、カスタムのスクリプタブルレンダーパイプラインの簡略化された例です。
これは、基本的なレンダーループがどのように機能するかを示しています。 最も効率的なランタイムパフォーマンスというよりは、最も明確なワークフローを示しています。
*/
using UnityEngine;
using UnityEngine.Rendering;
public class ExampleRenderPipeline : RenderPipeline {
public ExampleRenderPipeline() {
}
protected override void Render (ScriptableRenderContext context, Camera[] cameras) {
// 現在のレンダーターゲットを消去するコマンドを作成してスケジューリングします
var cmd = new CommandBuffer();
cmd.ClearRenderTarget(true, true, Color.black);
context.ExecuteCommandBuffer(cmd);
cmd.Release();
// すべてのカメラに繰り返します
foreach (Camera camera in cameras)
{
// 現在のカメラからカリングパラメーターを取得します
camera.TryGetCullingParameters(out var cullingParameters);
// カリングパラメーターを使用してカリング操作を実行し、結果を保存します
var cullingResults = context.Cull(ref cullingParameters);
// 現在のカメラに基づいて、ビルトインのシェーダー変数の値を更新します
context.SetupCameraProperties(camera);
// LightMode パスタグの値に基づいて、 Unity に描画するジオメトリを指示します
ShaderTagId shaderTagId = new ShaderTagId("ExampleLightModeTag");
//現在のカメラに基づいて、Unity にジオメトリを並べ替える方法を指示します
var sortingSettings = new SortingSettings(camera);
// どのジオメトリを描画するかとその描画方法を説明する DrawingSettings 構造体を作成します
DrawingSettings drawingSettings = new DrawingSettings(shaderTagId, sortingSettings);
// カリング結果をフィルタリングする方法を Unity に指示し、描画するジオメトリをさらに指定します
// FilteringSettings.defaultValue を使用して、フィルタリングなしを指定します
FilteringSettings filteringSettings = FilteringSettings.defaultValue;
// 定義した設定に基づいて、ジオメトリを描画するコマンドをスケジューリングします
context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
// 必要に応じて、スカイボックスを描画するコマンドをスケジューリングします
if (camera.clearFlags == CameraClearFlags.Skybox && RenderSettings.skybox != null)
{
context.DrawSkybox(camera);
}
// スケジュールされたすべてのコマンドを実行するようにグラフィックス API に指示します
context.Submit();
}
}
}
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.