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

頂点シェーダーと Fragment シェーダーのプログラミング

ShaderLab は単なるハードウェアシェーダー以上の機能を含み、さまざまなことができます。まず、Properties(プロパティー:属性)はマテリアルのインスペクターに表示するものや、違うグラフィックスハードで動けるように複数のシェーダーを含んだり、ハードが用意した固定関数を調整したり、などなどです。実際のプログラマブルシェーダー(頂点シェーダーや Fragment シェーダーのプログラムのような)は ShaderLab のシェーダーのコンセプトの単なる一部です。シェーダー: 頂点とフラグメントプログラム で基本的な説明をします。ここではローレベルなハードに近いシェーダーを __shader programs__と呼ぶことにします。

もしライティングに反応するシェーダーを書きたいなら、サーフェスシェーダーの記述 を読んでください。 またサンプルをお探しの場合は、頂点とフラグメントシェーダーの例 を参照してください。ここでは、Unity のライトで反応しないシェーダーについて言及します。(例:スペシャルエフェクト、イメージエフェクト 等)

シェーダープログラムは Cg / HLSL 言語で書かれています。シェーダーテキストの Pass コマンドの中に「スニペット」が埋め込まれます。だいたい以下のような感じになります。

  Pass {
      // ... the usual pass state setup ...
      
      CGPROGRAM
      // compilation directives for this snippet, e.g.:
      #pragma vertex vert
      #pragma fragment frag
      
      // the Cg/HLSL code itself
      
      ENDCG
      // ... the rest of pass setup ...
  }

Cg スニペット

Cg/HLSL プログラムスニペットは CGPROGRAMENDCG 間に書かれます。

まずは #pragma ステートメントで始まります。ここの命令はコンパイルするため、どんなシェーダー関数なのかを指し示しています。

  • #pragma vertex name - 頂点シェーダーとして定義される name という名前の関数
  • #pragma fragment name - Fragment シェーダーとして定義される name という名前の関数
  • _#pragma geometry name_ - DX10 のジオメトリシェーダーとして定義される name という名前の関数。以下に説明するように、このオプションは自動的に #pragma target 4.0 をオンにします。
  • _#pragma hull name_ - DX11 の Hull シェーダーとして定義される name という名前の関数。以下に説明するように、このオプションは自動的に #pragma target 5.0 をオンにします。
  • _#pragma domain name_ - DX11 の Domein シェーダーとして定義される name という名前の関数。以下に説明するように、このオプションは自動的に #pragma target 5.0 をオンにします。

その他のコンパイル命令

  • #pragma target name - コンパイルするシェーダーターゲットの指定。詳細は シェーダーコンパイルターゲットレベル を参照してください。
  • #pragma only_renderers space separated names - 指定のレンダラーのみシェーダーをコンパイルします。デフォルトではすべてのレンダラーのシェーダーがコンパイルされます。詳細は レンダラー を参照してください。
  • #pragma exclude_renderers space separated names - 指定のレンダラーのみシェーダーをコンパイルしません。デフォルトではすべてのレンダラーのシェーダーがコンパイルされます。詳細は レンダラー を参照してください。
  • #pragma multi_compile …_ - マルチシェーダーバリアント とともに動作します。
  • #pragma enable_d3d11_debug_symbols - DirectX 11 用にコンパイルされたシェーダーのデバッグ情報を生成します。これにより、Visual Studio 2012 (またはそれ以降のバージョン)のグラフィックスデバッガーを経由してシェーダーのデバッグが可能になります。

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

Unity 5.0 上で実行しても何も起こらないコンパイル命令で、安全に削除できるもの: #pragma glsl, #pragma glsl_no_auto_normalization, #pragma profileoption, #pragma fragmentoption

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

Unity はいくつかのレンダリング API (すなわち Direct3D 9 と OpenGL )をサポートし、デフォルトですべてのシェーダープログラムはサポートされているレンダラーにコンパイルされます。どのレンダラーにコンパイルするかは #pragma only_renderers あるいは #pragma exclude_renderers ディレクティブで指定できます。これは、特定のシェーダーがあるレンダラーでしか使用できず他では使用できない場合に便利です。現在サポートされているレンダラーの名前は以下のとおりです。

  • d3d9 - Direct3D 9.
  • d3d11 - Direct3D 11/12.
  • glcore - OpenGL 3.x/4.x.
  • gles - OpenGL ES 2.0.
  • gles3 - OpenGL ES 3.x.
  • metal - iOS/Mac Metal.
  • d3d11_9x - 一般的には WSA/WP8 プラットフォーム上で使用される Direct3D 11 9.x フィーチャーレベル。
  • xbox360 - Xbox 360.
  • xboxone - Xbox One.
  • ps3 - PlayStation 3.
  • ps4 - PlayStation 4.
  • psp2 - PlayStation Vita.
  • n3ds - Nintendo 3DS.
  • wiiu - Nintendo Wii U.

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

#pragma only_renderers d3d9

関連項目

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