Version: Unity 6.0 (6000.0)
言語 : 日本語
URP でカメラの出力をレンダーテクスチャに描画する
URP でカメラがレンダリングする順序

URP のレンダーリクエストの作成

ユニバーサルレンダーパイプライン (URP) レンダリングループ外のレンダーテクスチャにレンダリングするカメラをトリガーするには、C# スクリプトで SubmitRenderRequest API を使用します。

この例では、レンダーリクエストとコールバックを使用して、これらのリクエストの進行状況を監視する方法を示します。コードサンプル全体は、コード例 セクションで確認できます。

カメラスタックの 1 台のカメラのレンダリング

カメラのフルスタックを考慮せずに 1 台のカメラをレンダリングするには、UniversalRenderPipeline.SingleCameraRequest API を使用します。以下の手順に従ってください。

  1. SingleCameraRenderRequestExample という C# スクリプトを作成し、以下に示す using ステートメントを追加します。

    using System.Collections;
    using UnityEngine;
    using UnityEngine.Rendering;
    using UnityEngine.Rendering.Universal;
    
    public class SingleCameraRenderRequestExample : MonoBehaviour
    {
    
    }
    
  2. レンダリング元とレンダリング先のカメラとレンダーテクスチャを格納する配列を作成します。

    public class SingleCameraRenderRequestExample : MonoBehaviour
    {
        public Camera[] cameras;
        public RenderTexture[] renderTextures;
    }
    
  3. Start メソッドに、スクリプトの実行に進む前に camerasrenderTextures の配列が有効で正しいデータが含まれていることを確認するチェックを追加します。

    void Start()
    {
        // Make sure all data is valid before you start the component
        if (cameras == null || cameras.Length == 0 || renderTextures == null || cameras.Length != renderTextures.Length)
        {
            Debug.LogError("Invalid setup");
            return;
        }
    }
    
  4. SingleCameraRenderRequest クラス内で名前 SendSingleRenderRequests と戻り値の型 void を持つメソッドを作成します。

  5. 以下に示すように、SendSingleRenderRequests メソッドに cameras 配列を反復する for ループを追加します。

    void SendSingleRenderRequests()
    {
        for (int i = 0; i < cameras.Length; i++)
        {
    
        }
    }
    
  6. for ループ内で、UniversalRenderPipeline.SingleCameraRequest 型のレンダーリクエストを request という名前の変数に作成します。次に、アクティブなレンダーパイプラインがこのレンダーリクエストの型をサポートしているかどうかを RenderPipeline.SupportsRenderRequest で確認します。

  7. アクティブなレンダーパイプラインがレンダーリクエストをサポートしている場合は、カメラ出力の宛先を renderTextures 配列の一致するレンダーテクスチャに設定します。次に、レンダーリクエストを RenderPipeline.SubmitRenderRequest で送信します。

    void SendSingleRenderRequests()
    {
        for (int i = 0; i < cameras.Length; i++)
        {
            UniversalRenderPipeline.SingleCameraRequest request =
                new UniversalRenderPipeline.SingleCameraRequest();
    
            // Check if the active render pipeline supports the render request
            if (RenderPipeline.SupportsRenderRequest(cameras[i], request))
            {
                // Set the destination of the camera output to the matching RenderTexture
                request.destination = renderTextures[i];
                    
                // Render the camera output to the RenderTexture synchronously
                // When this is complete, the RenderTexture in renderTextures[i] contains the scene rendered from the point
                // of view of the Camera in cameras[i]
                RenderPipeline.SubmitRenderRequest(cameras[i], request);
            }
        }
    }
    
  8. SendSingleRenderRequest メソッドの上に、RenderSingleRequestNextFrame という IEnumerator インターフェースを作成します。

  9. RenderSingleRequestNextFrame 内で、メインカメラがレンダリングを終了するのを待ってから、SendSingleRenderRequest を呼び出します。フレームの終了を待ってから、StartCoroutine でコルーチンの RenderSingleRequestNextFrame を再開します。

    IEnumerator RenderSingleRequestNextFrame()
    {
        // Wait for the main camera to finish rendering
        yield return new WaitForEndOfFrame();
    
        // Enqueue one render request for each camera
        SendSingleRenderRequests();
    
        // Wait for the end of the frame
        yield return new WaitForEndOfFrame();
    
        // Restart the coroutine
        StartCoroutine(RenderSingleRequestNextFrame());
    }
    
  10. Start メソッドで、StartCoroutine を使用してコルーチンの RenderSingleRequestNextFrame を呼び出します。

    void Start()
    {
        // Make sure all data is valid before you start the component
        if (cameras == null || cameras.Length == 0 || renderTextures == null || cameras.Length != renderTextures.Length)
        {
            Debug.LogError("Invalid setup");
            return;
        }
    
        // Start the asynchronous coroutine
        StartCoroutine(RenderSingleRequestNextFrame());
    }
    
  11. エディターで、シーンに空のゲームオブジェクトを作成し、SingleCameraRenderRequestExample.csコンポーネント として追加します。

  12. Inspector ウィンドウで、レンダリング元のカメラを cameras リストに追加し、レンダリング先のレンダーテクスチャを renderTextures リストに追加します。

ノート:cameras リスト内のカメラの数と、renderTextures リスト内のレンダーテクスチャの数は同じである必要があります。

これで再生モードを開始すると、追加したカメラが追加したレンダーテクスチャにレンダリングされます。

カメラがレンダリングを終了したタイミングの確認

カメラがレンダリングを終了したタイミングを確認するには、RenderPipelineManager API から任意のコールバックを使用します。

以下の例では、RenderPipelineManager.endContextRendering コールバックを使用します。

  1. using System.Collections.GenericSingleCameraRenderRequestExample.cs ファイルの先頭に追加します。

  2. Start メソッドの終了時に、endContextRendering コールバックにサブスクライブします。

    void Start()
    {
        // Make sure all data is valid before you start the component
        if (cameras == null || cameras.Length == 0 || renderTextures == null || cameras.Length != renderTextures.Length)
        {
            Debug.LogError("Invalid setup");
            return;
        }
    
        // Start the asynchronous coroutine
        StartCoroutine(RenderSingleRequestNextFrame());
            
        // Call a method called OnEndContextRendering when a camera finishes rendering
        RenderPipelineManager.endContextRendering += OnEndContextRendering;
    }
    
  3. OnEndContextRendering というメソッドを作成します。Unity は、endContextRendering コールバックがトリガーしたときにこのメソッドを実行します。

    void OnEndContextRendering(ScriptableRenderContext context, List<Camera> cameras)
    {
        // Create a log to show cameras have finished rendering
        Debug.Log("All cameras have finished rendering.");
    }
    
  4. endContextRendering コールバックから OnEndContextRendering メソッドをサブスクライブ解除するには、SingleCameraRenderRequestExample クラスに OnDestroy メソッドを追加します。

    void OnDestroy()
    {
        // End the subscription to the callback
        RenderPipelineManager.endContextRendering -= OnEndContextRendering;
    }
    

このスクリプトは以前と同じように動作しますが、どのカメラがレンダリングを終了したかをコンソールウィンドウに記録します。

コード例

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class SingleCameraRenderRequest : MonoBehaviour
{
    public Camera[] cameras;
    public RenderTexture[] renderTextures;

    void Start()
    {
        // Make sure all data is valid before you start the component
        if (cameras == null || cameras.Length == 0 || renderTextures == null || cameras.Length != renderTextures.Length)
        {
            Debug.LogError("Invalid setup");
            return;
        }

        // Start the asynchronous coroutine
        StartCoroutine(RenderSingleRequestNextFrame());
        
        // Call a method called OnEndContextRendering when a camera finishes rendering
        RenderPipelineManager.endContextRendering += OnEndContextRendering;
    }

    void OnEndContextRendering(ScriptableRenderContext context, List<Camera> cameras)
    {
        // Create a log to show cameras have finished rendering
        Debug.Log("All cameras have finished rendering.");
    }

    void OnDestroy()
    {
        // End the subscription to the callback
        RenderPipelineManager.endContextRendering -= OnEndContextRendering;
    }

    IEnumerator RenderSingleRequestNextFrame()
    {
        // Wait for the main camera to finish rendering
        yield return new WaitForEndOfFrame();

        // Enqueue one render request for each camera
        SendSingleRenderRequests();

        // Wait for the end of the frame
        yield return new WaitForEndOfFrame();

        // Restart the coroutine
        StartCoroutine(RenderSingleRequestNextFrame());
    }

    void SendSingleRenderRequests()
    {
        for (int i = 0; i < cameras.Length; i++)
        {
            UniversalRenderPipeline.SingleCameraRequest request =
                new UniversalRenderPipeline.SingleCameraRequest();

            // Check if the active render pipeline supports the render request
            if (RenderPipeline.SupportsRenderRequest(cameras[i], request))
            {
                // Set the destination of the camera output to the matching RenderTexture
                request.destination = renderTextures[i];
                
                // Render the camera output to the RenderTexture synchronously
                RenderPipeline.SubmitRenderRequest(cameras[i], request);

                // At this point, the RenderTexture in renderTextures[i] contains the scene rendered from the point
                // of view of the Camera in cameras[i]
            }
        }
    }
}
URP でカメラの出力をレンダーテクスチャに描画する
URP でカメラがレンダリングする順序
Copyright © 2023 Unity Technologies
优美缔软件(上海)有限公司 版权所有
"Unity"、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属机构在美国及其他地区的商标或注册商标。其他名称或品牌是其各自所有者的商标。
公安部备案号:
31010902002961