DX11/OpenGL コアのテッセレーションを伴うサーフェスシェーダー
頂点シェーダーとフラグメントシェーダーの例

頂点シェーダーとフラグメントシェーダーの記述

ShaderLab シェーダーは単なるハードウェアシェーダー以上の機能を含み、さまざまなことができます。ShaderLab シェーダーは Material インスペクターに表示されたプロパティーの記述、さまざまなグラフィックスハードウェア用の複数のシェーダーの実装、固定関数のハードウェア状態の設定などを行います。実際のプログラマブルシェーダー (頂点シェーダーやフラグメントシェーダーのプログラムなど) は ShaderLab のシェーダーのコンセプトの単なる一部です。導入的な説明は、シェーダー: 頂点とフラグメントプログラム を参照してください。ここでは低レベルなハードウェアシェーダーを シェーダープログラム と呼ぶことにします。

**ライティングと相互作用するシェーダーを作成する場合は、サーフェスシェーダー のドキュメントを参照してください。いくつか例を見るには 頂点シェーダーとフラグメントシェーダーの例 を参照してください。このページの残りの部分は、シェーダーが Unity のライト (例えば、特殊効果、ポストプロセスエフェクト など) と相互作用しないことを前提としています。

シェーダープログラムは HLSL 言語 で記述され、シェーダーテキストに “スニペット” を埋め込んで Pass コマンドの任意の場所に置かれます。 通常は以下のようになります。

  Pass {
        // ...通常の pass  設定...
      
        CGPROGRAM
        // このスニペットのコンパイラーディレクティブ。例:
        #pragma vertex vert
        #pragma fragment frag
      
        // the Cg/HLSL code itself
      
        ENDCG
        // ... pass  設定の残り ...
    }

HLSL スニペット

HLSL プログラムスニペットは CGPROGRAMENDCG のキーワードの間、または、HLSLPROGRAMENDHLSL の間に記述します。2 番目の形式では、自動的には HLSLSupport と UnityShaderVariables ビルトインヘッダーファイル含まれません

スニペットの開始で、コンパイラーディレクティブは #pragma ステートメントではじまります。ディレクティブはどのシェーダー関数を使ってコンパイルするかを示します。

  • #pragma vertex name - 関数 name を頂点シェーダーとしてコンパイル
  • #pragma fragment name - 関数 name をフラグメントシェーダーとしてコンパイル
  • #pragma geometry name - 関数 name を DX10 のジオメトリシェーダーとしてコンパイル。このオプションがあると、自動的に後述の #pragma target 4.0 をオンにします。
  • #pragma hull name - 関数 name を DX11 の Hull シェーダーとしてコンパイル。このオプションがあると、自動的に後述の #pragma target 5.0 をオンにします。
  • #pragma domain name - 関数 name を DX11 のドメインシェーダーとしてコンパイル。このオプションがあると、自動的に後述の #pragma target 5.0 をオンにします。

その他のコンパイラーディレクティブ

  • #pragma target name - コンパイルするシェーダーターゲットの指定。詳細は シェーダーコンパイルターゲットレベル を参照してください。
  • #pragma require feature … - シェーダーが必要とする GPU 機能を細かく制御します。詳しくは シェーダーコンパイルターゲット を参照してください。
  • #pragma only_renderers space separated names - 指定のレンダラー用にのみシェーダーをコンパイルします。デフォルトではすべてのレンダラー用にシェーダーがコンパイルされます。詳細は後述の Renderers を参照してください。
  • #pragma exclude_renderers space separated names - 指定のレンダラーにのみシェーダーをコンパイルしません。デフォルトではすべてのレンダラー用にシェーダーがコンパイルされます。詳細は Renderers を参照してください。
  • #pragma multi_compile … - マルチシェーダーバリアント とともに動作します。
  • #pragma enable_d3d11_debug_symbols - DirectX 11 用にコンパイルされたシェーダーのデバッグ情報を生成します。これにより、Visual Studio 2012 (またはそれ以降のバージョン)のグラフィックスデバッガを経由してシェーダーのデバッグが可能になります。
  • #pragma hardware_tier_variants renderer name - 選択されたレンダラーを実行する各ハードウェア階層のために、コンパイルしたシェーダーごとの 複数シェーダーハードウェアバリアント を生成します。詳細は、後述の Renderers を参照してください。
  • #pragma hlslcc_bytecode_disassembly - 逆アセンブルした HLSLcc バイトコードを変換されたシェーダーに埋め込みます。
  • #pragma disable_fastmath - ほとんどの場合 NaN ハンドリングを伴う正確な IEEE 754 規格を有効にします (現在は Metal プラットフォームのみに影響します)。
  • #pragma glsl_es2 - GLSL シェーダーで設定する場合、シェーダーターゲットが OpenGL ES 3 の場合でも、GLSL ES 1.0 (OpenGL ES 2.0) を生成します。

それぞれのスニペットには最低でも頂点プログラムとフラグメントプログラムが含まれていなければいけません。それゆえに #pragma vertex#pragma fragment 命令が必要になります。

以下のコンパイル命令は、Unity 5.0 上で実行しても何も発生せず、安全に削除できます。#pragma glsl#pragma glsl_no_auto_normalization#pragma profileoption#pragma fragmentoption

Unity は #pragma ディレクティブのみをシェーダーファイルでサポートし、インクルードファイルではサポートしません。

レンダリングプラットフォーム

Unity はいくつかのレンダリング API (例えば Direct3D 11 と OpenGL) をサポートしており、デフォルトではすべてのシェーダープログラムは、サポートされているすべてのレンダラーにコンパイルされます。#pragma only_renderers または #pragma exclude_renderers ディレクティブを使用してどのレンダラーをコンパイルするかを指定できます。これは、一部のプラットフォームでは使用不可であることが分かっているシェーダー言語の機能を、明示的に使用する場合に最も役立ちます。サポートされているレンダラー名は以下のとおりです。

  • d3d11 - Direct3D 11/12
  • glcore - OpenGL 3.x/4.x
  • gles - OpenGL ES 2.0
  • gles3 - OpenGL ES 3.x
  • metal - iOS/Mac Metal
  • vulkan - Vulkan
  • d3d11_9x - Direct3D 11 9.x 機能レベル (WSA プラットフォームで一般に使用されている)
  • xboxone - Xbox One
  • ps4 - PlayStation 4
  • n3ds - Nintendo 3DS
  • wiiu - Nintendo Wii U

例えば、次の行は、シェーダーを D3D11 モードにのみコンパイルします。

#pragma only_renderers d3d11

関連項目


  • 2018–03–20 編集レビュー を行って修正されたページ
  • シェーダー #pragma ディレクティブは Unity 2018.1 で追加
DX11/OpenGL コアのテッセレーションを伴うサーフェスシェーダー
頂点シェーダーとフラグメントシェーダーの例