Version: 2021.2
言語: 日本語
シェーダーの基礎
シェーダーアセット

Shader クラス

Unityでは、グラフィックスパイプライン の一部であるシェーダーを使う場合、通常、Shader クラスのインスタンスを使用します。Shader クラスのインスタンスは、シェーダーオブジェクト と呼ばれます。

シェーダーオブジェクトは、シェーダープログラムを使うための Unity 特有の方法です。シェーダーオブジェクトは、シェーダープログラムやその他の情報のラッパーです。これを使うことにより、1 つのファイル内で複数のシェーダープログラムを定義し、それらの使用方法を Unity に指示できます。

レンダーパイプラインの互換性

機能名 ビルトインレンダーパイプライン ユニバーサルレンダーパイプライン (URP) HD レンダーパイプライン (HDRP) カスタム SRP
シェーダーオブジェクト はい はい はい はい

シェーダーオブジェクトの基礎

シェーダーオブジェクトには、シェーダープログラム、GPU 上での設定を変更するための指示 (総称はレンダー状態)、それらをどのように使用するかを Unity に伝える情報が含まれています。

シーンの外観を決定するには、マテリアル を持つシェーダーオブジェクトを使います。

アセット

シェーダーオブジェクトは 2 つの方法で作成できます。それぞれに特有のアセットタイプがあります。

どちらの方法でシェーダーオブジェクトを作成しても、その結果は内部的には同様に示されます。

シェーダーオブジェクトの内部

シェーダーオブジェクトはネスト構造になっています。サブシェーダーパス と呼ばれる構造に情報を整理します。シェーダープログラムは シェーダーバリアント に整理されます。

シェーダーオブジェクト

シェーダーオブジェクトには以下が含まれています。

  • 名前など、それ自体の情報
  • フォールバックシェーダーオブジェクト。Unity がこのシェーダーオブジェクトを使用できない場合に、フォールバックシェーダーオブジェクトが使用されます。
  • 1 つまたは複数のサブシェーダー

また、共有シェーダーコードや、カスタムエディター を使用するかどうかなどの追加情報を定義することもできます。シェーダーオブジェクトの定義については、ShaderLab: シェーダーオブジェクトの定義 を参照してください。

SubShader

SubShader (サブシェーダー) は、シェーダーオブジェクトを、異なるハードウェア、レンダーパイプライン、ランタイム設定に対応する部分に分離することができます。

SubShader には以下が含まれています。

  • このサブシェーダーが対応できるハードウェア、レンダーパイプライン、ランタイム設定についての情報。
  • サブシェーダー タグ (サブシェーダーに関する情報を提供するキーと値のペア)。
  • 1 つまたは複数のパス

また、すべてのパスに共通するレンダー状態などの追加情報を定義することもできます。サブシェーダーで定義できるすべての内容については、ShaderLab: サブシェーダーの定義 を参照してください。

Pass

Pass (パス) には以下が含まれています。

  • Pass タグ (パスに関する情報を提供するキーと値のペア)。
  • シェーダープログラムを実行する前にレンダー状態を更新するための指示
  • 1 つまたは複数のシェーダバリアントにまとめられたシェーダープログラム

また、名前などの追加情報を定義することもできます。パスで定義できるすべての内容については、ShaderLab: パスの定義 を参照してください。

シェーダーバリアント

パスに含まれるシェーダープログラムは、シェーダーバリアントとして整理されます。シェーダーバリアントはコードを共有しますが、指定するキーワードを有効または無効にすると異なる機能を持ちます。

1 つのパスに含まれるシェーダーバリアントの数は、シェーダーコードで定義されたキーワードの数と、ターゲットプラットフォームによって異なります。各パスには少なくとも 1 つのバリアントが含まれます。

詳しくは、シェーダーバリアント を参照してください。

レンダリング時の操作順序

以下は、すべてのレンダーパイプラインにおいて、シェーダーオブジェクトを使ってジオメトリを描画する方法についての上級者向けの説明です。

Unity がシェーダーオブジェクトを使う前に以下を行います。

  1. Unity はシェーダーオブジェクトのサブシェーダーのリストを作成します。シェーダーオブジェクトに定義されているすべてのサブシェーダーを加え、次に、フォールバックのシェーダーオブジェクトにあるすべてのサブシェーダーを順に加えます。

Unity がシェーダーオブジェクトを使用して初めてジオメトリをレンダリングするとき、または、シェーダーの LOD 値 またはアクティブなレンダーパイプラインが変更されるときは、以下の通りです。

  1. Unity はすべてのサブシェーダーのリストを反復し、それらが “デバイスハードウェアに対応するか”、“現在のシェーダーの LOD 値以下か”、“アクティブなレンダーパイプラインに対応するか” を調べ判断します。
  2. リストにこれらの要件を満たす 1 つ以上のサブシェーダーが含まれている場合、最初のものが選択されます。これがアクティブなサブシェーダーです。
  3. リストにすべての要件を満たすサブシェーダーが含まれていない場合は、以下の通りです。
    1. リストにハードウェアの要件を満たす (ただし、LOD とレンダーパイプラインの要件は満たさない) 1 つ以上のサブシェーダーが含まれている場合、Unity は最初のものを選択します。これがアクティブなサブシェーダーです。
    2. リストにハードウェア要件を満たすサブシェーダーが含まれていない場合、エラーのマテリアルを表示します。

Unity は、同じシェーダーバリアントを使用しているジオメトリを識別し、より効率的なレンダリングを行うために、バッチ に整理します。ジオメトリの各バッチに対して、フレームごとに 1 回、以下を行います。

  1. Unity は、アクティブなサブシェーダーのどのパスを、フレームのどの時点で描画すべきかを決定します。この動作はレンダーパイプラインによって異なります。
  2. レンダリングするすべてのパスに対して以下を行います。
    1. 現在のレンダー状態が、パスで定義されたレンダー状態と一致しない場合、Unity はパスで定義されたレンダー状態を設定します。
    2. GPU は、関連するシェーダーバリアントを使用してジオメトリをレンダリングします。
シェーダーの基礎
シェーダーアセット