docs.unity3d.com
    目次を表示する/隠す

    XR のシングルパスインスタンスレンダリングでフルスクリーン転送を実行する方法

    このページの例は、XR のシングルパスインスタンスレンダリングでフルスクリーン転送を実行するカスタム Renderer Feature を作成する方法を示しています。

    例の概要

    この例では、以下のソリューションを実装します。

    • カスタム レンダーパス を呼び出す カスタム Renderer Feature。

    • この レンダーパス は、不透明なテクスチャを、現在のレンダラーの カメラのカラーターゲット に転送します。レンダーパスはコマンドバッファを使用して、両目のフルスクリーンメッシュを描画します。

    この例には、レンダリングの GPU 面を実行する シェーダー が含まれています。このシェーダーは、XR サンプラーマクロを使用してカラーバッファをサンプリングします。

    前提条件

    この例の前提条件は以下のとおりです。

    • Scriptable Render Pipeline Settings プロパティが URP アセットを参照している (Project Settings > Graphics > Scriptable Render Pipeline Settings)。

    サンプルのシーンとゲームオブジェクトの作成

    この例のステップを実行するために、以下のゲームオブジェクトが含まれる新しいシーンを作成します。

    1. キューブを作成します。メインカメラからキューブがはっきりと見えるようにします。

    これで、この例のステップの実行に必要なシーンを用意できました。

    実装例

    このセクションは、サンプルのシーンとゲームオブジェクトの作成 の説明のとおりにシーンが作成されていることを前提としています。

    以下の手順に従って、カスタム レンダーパス を使用する カスタム Renderer Feature を作成します。

    1. 新しい C# スクリプトを作成します。ColorBlitRendererFeature.cs という名前を付けます。このスクリプトは、カスタム Renderer Feature を実装します。

      using UnityEngine;
      using UnityEngine.Rendering;
      using UnityEngine.Rendering.Universal;
      
      internal class ColorBlitRendererFeature : ScriptableRendererFeature
      {
          public Shader m_Shader;
          public float m_Intensity;
      
          Material m_Material;
      
          ColorBlitPass m_RenderPass = null;
      
          public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
          {
              if (renderingData.cameraData.cameraType == CameraType.Game)
              {
                  // ScriptableRenderPassInput.Color 引数を指定して ConfigureInput を呼び出すことで、レンダーパスで不透明なテクスチャを利用できるようにします
                  m_RenderPass.ConfigureInput(ScriptableRenderPassInput.Color);
                  m_RenderPass.SetTarget(renderer.cameraColorTarget, m_Intensity);
                  renderer.EnqueuePass(m_RenderPass);
              }
          }
      
          public override void Create()
          {
              if (m_Shader != null)
                  m_Material = new Material(m_Shader);
      
              m_RenderPass = new ColorBlitPass(m_Material);
          }
      
          protected override void Dispose(bool disposing)
          {
              CoreUtils.Destroy(m_Material);
          }
      }
      
    2. 新しい C# スクリプトを作成します。ColorBlitPass.cs という名前を付けます。このスクリプトは、カスタム転送ドローコールを実行するカスタムレンダーパスを実装します。

      このレンダーパスは、cmd.DrawMesh メソッドを使用して、フルスクリーンクアッドを描画し、転送処理を実行します。

      ノート: cmd.Blit メソッドは URP XR 統合との互換性に問題があるため、URP XR プロジェクトでは使用しないでください。cmd.Blit を使用すると、XR シェーダーキーワードが暗黙的に有効または無効になり、XR SPI レンダリングが停止する可能性があります。

      using UnityEngine;
      using UnityEngine.Rendering;
      using UnityEngine.Rendering.Universal;
      
      internal class ColorBlitPass : ScriptableRenderPass
      {
          ProfilingSampler m_ProfilingSampler = new ProfilingSampler("ColorBlit");
          Material m_Material;
          RenderTargetIdentifier m_CameraColorTarget;
          float m_Intensity;
      
          public ColorBlitPass(Material material)
          {
              m_Material = material;
              renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
          }
      
          public void SetTarget(RenderTargetIdentifier colorHandle, float intensity)
          {
              m_CameraColorTarget = colorHandle;
              m_Intensity = intensity;
          }
      
          public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
          {
              ConfigureTarget(new RenderTargetIdentifier(m_CameraColorTarget, 0, CubemapFace.Unknown, -1));
          }
      
          public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
          {
              var camera = renderingData.cameraData.camera;
              if (camera.cameraType != CameraType.Game)
                  return;
      
              if (m_Material == null)
                  return;
      
              CommandBuffer cmd = CommandBufferPool.Get();
              using (new ProfilingScope(cmd, m_ProfilingSampler))
              {
                  m_Material.SetFloat("_Intensity", m_Intensity);
                  cmd.SetRenderTarget(new RenderTargetIdentifier(m_CameraColorTarget, 0, CubemapFace.Unknown, -1));
                  // RenderingUtils.fullscreenMesh 引数で、描画するメッシュがクアッドであることを指定します。
                  cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_Material);
              }
              context.ExecuteCommandBuffer(cmd);
              cmd.Clear();
      
              CommandBufferPool.Release(cmd);
          }
      }
      
    3. 転送処理を実行するシェーダーを作成します。シェーダーファイルに ColorBlit.shader という名前を付けます。vertex 関数はフルスクリーンクアッドの位置を出力します。fragment 関数はカラーバッファをサンプリングし、値 color * float4(0, _Intensity, 0, 1) をレンダーターゲットに返します。

      Shader "ColorBlit"
      {
              SubShader
          {
              Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline"}
              LOD 100
              ZWrite Off Cull Off
              Pass
              {
                  Name "ColorBlitPass"
      
                  HLSLPROGRAM
                  #pragma vertex vert
                  #pragma fragment frag
                  #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
      
                  struct Attributes
                  {
                      float4 positionHCS   : POSITION;
                      float2 uv           : TEXCOORD0;
                      UNITY_VERTEX_INPUT_INSTANCE_ID
                  };
      
                  struct Varyings
                  {
                      float4  positionCS  : SV_POSITION;
                      float2  uv          : TEXCOORD0;
                      UNITY_VERTEX_OUTPUT_STEREO
                  };
      
                  Varyings vert(Attributes input)
                  {
                      Varyings output;
                      UNITY_SETUP_INSTANCE_ID(input);
                      UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
      
                      // ノート: このパスはすでにクリップスペースに存在するメッシュを
                      // 使用して設定されているため、頂点の位置を出力するだけで
                      // 十分です
                      output.positionCS = float4(input.positionHCS.xyz, 1.0);
      
                      #if UNITY_UV_STARTS_AT_TOP
                      output.positionCS.y *= -1;
                      #endif
      
                      output.uv = input.uv;
                      return output;
                  }
      
                  TEXTURE2D_X(_CameraOpaqueTexture);
                  SAMPLER(sampler_CameraOpaqueTexture);
      
                  float _Intensity;
      
                  half4 frag (Varyings input) : SV_Target
                  {
                      UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
                      float4 color = SAMPLE_TEXTURE2D_X(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, input.uv);
                      return color * float4(0, _Intensity, 0, 1);
                  }
                  ENDHLSL
              }
          }
      }
      
    4. ColorBlitRendererFeature をユニバーサルレンダラーアセットに追加します。

      Renderer Feature の追加

      Renderer Feature を追加する方法の詳細については、Renderer Feature をレンダラーに追加する方法 のページを参照してください。

      この例では、Intensity プロパティを 1.5 に設定します。

    5. このサンプルを可視化するために、XR SDK を使用するようにプロジェクトを設定します。MockHMD XR プラグインをプロジェクトに追加 します。Render Mode プロパティを Single Pass Instanced に設定します。

      MockHMD の設定

      以下のようなビューが表示されます。

      最終的なシーンとゲームビュー

    6. 再生モードに入ります。カラーバッファが表示されます。

      最終的な再生モードのビュー

    これでこの例は完成です。

    トップに戻る
    Copyright © 2023 Unity Technologies — 商標と利用規約
    • 法律関連
    • プライバシーポリシー
    • クッキー
    • 私の個人情報を販売または共有しない
    • Your Privacy Choices (Cookie Settings)