ARDKにおけるレンダリング

アプリ内のカメラフィードのレンダリング方法をカスタマイズする。

概要

ARDKでは、設定可能なレンダリングパイプラインを利用できます。対象シーンに ARRenderingManager コンポーネントを追加することで(通常はシーンカメラオブジェクトに追加)、レンダリングパイプラインが画面に対してカメラフィードを確実にレンダリングできるようにします。

ARRenderingManagerコンポーネントは、ネイティブイメージがフレームごとに更新されて画面に継続的にレンダリングされる方法を設定および管理します。さらに、要求に応じてCPUまたはGPUメモリ内に(カメラ画像の)スナップショットテクスチャを生成することも可能です。

カスタムコマンドバッファを書く

ARDKのレンダリングパイプラインに加えて、Unityのカスタムグラフィックスコマンドバッファも使用できます。カスタムコマンドバッファは、Unityの CameraEvent.BeforeForwardOpaque またはレンダラーのGPUFenceのあとに実行されるべきものです。

深度情報とレンダリングパイプライン

カメラフィードデータのレンダリングに加えて、セッションが深度データを生成するよう設定されている場合は、ARDKのレンダーパイプラインがzバッファデータの生成も行います。そのため、対象シーンで深度生成を有効化する場合は、 ARDepthManager を使用するにしても、 ARSessionIsDepthEnabled に設定するにしても、シーンには ARRenderingManager が必須となります。 ARDepthManager を使う場合、 ARRenderingManager を追加したのと同じオブジェクトに ARDepthManager コンポーネントを追加する必要があります。

ARDepthManager から深度情報を取得する方法の詳細は、 深度データの生成 をご参照ください。

アウェアネスバッファを画面に合わせて調整する

深度バッファとセマンティックバッファでは、パイプラインが生成・利用するバッファは必ずしもデバイスのカメラまたは画面と一致するものではありません。ARDKでは DepthBufferProcessor.CopyToAlignedTextureARGB32DepthBufferProcessor.CopyToAlignedTextureRFloatSemanticBufferProcessor.CopyToAlignedTextureARGB32 を使ってバッファを調整する手法が利用可能ですが、これらの手法はピクセルごとの処理を用いるため時間がかかる場合があります。

より高速な代替手段は、適切なAwarenessProcessorから SamplerTransform を取得し、カスタムシェーダーで使用することです。たとえば次のARDepthManagerから SamplerTransform を取得できます:

Matrix4x4 samplerTransform = depthManager.DepthBufferProcessor.SamplerTransform;

それから使用したい未調整のテクスチャを取得します。たとえば深度バッファのフロートテクスチャなどです:

Texture2D depthTexture;

depthBuffer.CreateOrUpdateTextureRFloat(ref depthTexture);

未調整テクスチャとトランスフォームを使用して移行を垂直加工機能に適用するカスタムシェーダーを作成します:

Shader "Custom/DepthSh"
{

  ...

    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {

          ...

          // Transforms used to sample the context awareness textures
          float4x4 _depthTransform;

          v2f vert (appdata v)
          {
              v2f o;
              o.vertex = UnityObjectToClipPos(v.vertex);
              o.uv = v.uv;

              // Transform UVs for the context awareness textures
              o.depth_uv = mul(_depthTransform, float4(v.uv, 1.0f, 1.0f)).xyz;
              return o;
          }
...

最後に、必要に応じて対象シーン内のカスタム素材でこのシェーダーを使います。たとえば、調整した深度バッファテクスチャを画面へ転送するには OnRenderImage() が有効かもしれません:

public Material _shaderMaterial;

....

void OnRenderImage(RenderTexture source, RenderTexture destination)
{
    //pass in our raw depth texture
    _shaderMaterial.SetTexture("_DepthTex", depthTexture);

    //pass in our transform
    _shaderMaterial.SetMatrix("_depthTransform", samplerTransform);

    //blit everything with our shader
    Graphics.Blit(source, destination, _shaderMaterial);
}

深度バッファまたはセマンティックバッファの調整の各ステップ例は 中級チュートリアル: 深度テクスチャ中級チュートリアル: セマンティック セグメンテーションテクスチャ をご参照ください。

ARアップデートの取得

このステップはiOSプラットフォームでは不要ですが、Androidプラットフォームでは必要です。Androidの場合、ARアップデートは必ずコマンドバッファのコマンドから取得しなければなりません(このコマンドを実行しないと ARFrame アップデートが表出しません)。カスタムコマンドを使用したい場合、次を呼び出します:

yourCommandBuffer.IssuePluginEventAndData(yourARSession);

このARSessionBuffersHelperメソッドは、ARアップデートを取得するためにバッファにコマンドを追加するだけです。そのバッファの実行を設定するものではありません。コマンドバッファがARアップデートを起動するため、レンダリングループの一部のように繰り返し実行する必要があります。 ARCore は30fpsでアップデートするため、それ以上の数値を目指してください。

こちらもご覧ください

クラス

レンダリング

チュートリアル