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

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

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

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

Shader programs は 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 プログラムスニペットは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 - 指定のレンダラのみシェーダをコンパイルします。デフォルトでは全てのレンダラのシェーダがコンパイルされます。詳細はrenderers を参照下さい。
  • #pragma exclude_renderers space separated names - 指定のレンダラのみシェーダをコンパイルしません。デフォルトでは全てのレンダラのシェーダがコンパイルされます。詳細はrenderers を参照下さい。
  • #pragma glsl - デスクトップのOpenGLプロットフォーム向けにシェーダをコンパイルする場合,Cg/HLSLをGLSLに変換します(デフォルト設定ではARB頂点/フラグメントプログラム)。これによりデリバティブ指示,例えば明示的なLODレベルをもつテクスチャのサンプリングの場合,を有効化します。
  • #pragma multi_compile …_ - for working with multiple shader variants.
  • #pragma glsl_no_auto_normalization - モバイル向けGLSL (iOS/Android)シェーダをコンパイルするとき,法線/接線ベクトルの自動正規化をオフにします。デフォルトではiOS/Androidプラットフォームのシェーダにて法線/接線ベクトルは正規化されます。
  • #pragma enable_d3d11_debug_symbols - generate debug information for shaders compiled for DirectX 11, this will allow you to debug shaders via Visual Studio 2012 (or higher) Graphics debugger.

Each snippet must contain at least a vertex program and a fragment program. Thus #pragma vertex and #pragma fragment directives are required.

シェーダターゲット

デフォルトでは,Unityはシェーダをおおよそシェーダモデル2.0相当にコンパイルします。#pragma target を使用することでシェーダは他のレベルにコンパイルすることが出来ます。現在は次のターゲットがサポートされています:

  • #pragma target 2.0 (default) - おおよそシェーダモデル2.0相当
    • Shader Model 2.0 on Direct3D 9.
    • ARB_vertex_program with 256 instruction limit and ARB_fragment_program with 96 instruction limit (32 texture + 64 arithmetic), 16 temporary registers and 4 texture indirections.
  • #pragma target 3.0 - ターゲットをのシェーダモデル3.0にコンパイル:
    • Direct3D 9上のShader Model 3.0
    • ARB_vertex_program with no instruction limit and ARB_fragment_program with 1024 instruction limit (512 texture + 512 arithmetic), 32 temporary registers and 4 texture indirections. It is possible to override these limits using #pragma profileoption directive. E.g. #pragma profileoption MaxTexIndirections=256 raises texture indirections limit to 256. Note that some shader model 3.0 features, like derivative instructions, aren’t supported by ARB_vertex_program/ARB_fragment_program. You can use #pragma glsl to translate to GLSL instead which has fewer restrictions. 3.0より大きいターゲット向けにコンパイルするとき,頂点/フラグメントプログラムともに必要です。
  • #pragma target 4.0 - DX10シェーダーモデル4.0向けにコンパイルします。このターゲットは現在DirectX11レンダラのみでサポートされます。

  • #pragma target 5.0 - DX11シェーダーモデル5.0向けにコンパイルします。このターゲットは現在DirectX11レンダラのみでサポートされます。

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

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

  • d3d9 - Direct3D 9.
  • d3d11 - Direct3D 11.
  • opengl - OpenGL.
  • gles - OpenGL ES 2.0.
  • gles3 - OpenGL ES 3.0.
  • d3d11_9x - Direct3D 11 9.x feature level, as commonly used on WSA/WP8 platforms.
  • xbox360 - Xbox 360.
  • ps3 - PlayStation 3.
  • flash - Flash.

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

#pragma only_renderers d3d9
サーフェイス シェーダとDX11テッセレーション
頂点とフラグメントシェーダの例