シェーダーリファレンス
サーフェイスシェーダーの例

サーフェスシェーダーの記述

ライティングと相互作用するシェーダーの記述は複雑です。各種ライト、各種の影のオプション、各種レンダリングパス (フォワードやデファードレンダリング) があり、シェーダーはその複雑さを処理する必要があります。

Unity の サーフェスシェーダー はコードの生成方法で、低レベル 頂点/ピクセルシェーダープログラム を使用するよりもずっと簡単に lit シェーダーを作成できます。サーフェスシェーダーには、カスタムの言語、魔法や、忍者のような技はありません。サーフェスシェーダーは、手で書かなければならないすべての繰り返しのコードを生成するだけです。やはり、HLSL でシェーダーコードを書かなければなりません。

サンプルが必要な場合は、サーフェイスシェーダーの例サーフェイスシェーダーライティングの例 を参照してください。

どのように機能するか

入力として必要な UV やデータを取得し、出力構造体の SurfaceOutput に注入する「サーフェス関数」を定義します。SurfaceOutput は、基本的に サーフェスのプロパティー (アルべド、法線、エミッション、スペキュラーなど) を表します。 このコードは HLSL で作成します。

サーフェスシェーダーコンパイラーは、どんな入力が必要で、なにを出力するかなどを決定し、実際に 頂点シェーダーとピクセルシェーダー を生成します。もちろん、フォワードレンダリングやデファードレンダリングを処理するレンダリングパスもここで生成します。

サーフェスシェーダーが出力する標準的な構造体は次のようになります。

struct SurfaceOutput
{
    fixed3 Albedo;  // ディフューズ色
    fixed3 Normal;  // 書き込まれる場合は、接線空間法線
    fixed3 Emission;
    half Specular;  //  0..1 の範囲のスペキュラーパワー
    fixed Gloss;    // スペキュラー強度
    fixed Alpha;    // 透明度のアルファ
};

Unity 5 では、サーフェスシェーダーは物理ベースのライティングモデルも使えます。組み込まれた Standard や StandardSpecular のライティングモデル(以下参照)では、それぞれ、これらの出力構造を使えます。

struct SurfaceOutputStandard
{
    fixed3 Albedo;      // ベース (ディフューズかスペキュラー) カラー
    fixed3 Normal;      // 書き込まれる場合は、接線空間法線
    half3 Emission;
    half Metallic;      // 0=非メタル, 1=メタル
    half Smoothness;    // 0=粗い, 1=滑らか
    half Occlusion;     // オクルージョン (デフォルト 1)
    fixed Alpha;        // 透明度のアルファ
};
struct SurfaceOutputStandardSpecular
{
    fixed3 Albedo;      // ディフューズ色
    fixed3 Specular;    // スペキュラー色
    fixed3 Normal;      // 書き込まれる場合は、接線空間法線
    half3 Emission;
    half Smoothness;    // 0=粗い, 1=滑らか
    half Occlusion;     // オクルージョン (デフォルト 1)
    fixed Alpha;        // 透明度のアルファ
};

サンプル

サーフェイスシェーダーの例 サーフェースシェーダーのカスタムライティングのサンプル DX11 / OpenGL コアテッセレーションのサーフェースシェーダー のページを参照してください .

サーフェスシェーダーコンパイルディレクティブ

その他のシェーダー同様、サーフェスシェーダーは CGPROGRAM..ENDCG ブロック内に置かれます。違いは以下のようになります。

  • Pass ではなく、SubShader ブロック内に配置される必要があります。サーフェスシェーダーは複数のパスでコンパイルされます。
  • #pragma surface ... ディレクティブを使用して、これがサーフェスシェーダーであることを示しています。

#pragma surface ディレクティブは次のようになります。

#pragma surface surfaceFunction lightModel [optionalparams]

必要なパラメーター

  • surfaceFunction - Cg で記述されたサーフェスシェーダーの関数です。これは、void surf (Input IN, inout SurfaceOutput o) という関数を持つことを意味します。ここの Input は前もって定義した構造体になります。Input は、surface 関数が必要とするテクスチャ座標と追加の自動変数を含む必要があります。
  • lightModel - 使用するライティングモデル。組み込みライティングモデルは、Lambert (デフューズ) と BlinnPhong (スペキュラ) です。自前のライティングモデルを記述する方法に関しては、サーフェイスシェーダーでのカスタムライティングモデル ページを参照してください。 \t* ライティングモデル Standard は出力構造体 SurfaceOutputStandard を使用し、 Unity の Standard (Metallic ワークフロー)シェーダーにマッチします。
  • ライティングモデル StandardSpecular は出力構造体 SurfaceOutputStandardSpecular を使用し、Unity の スタンダード(Specular 設定) シェーダーにマッチします。 * ライティングモデル LambertBlinnPhong は物理ベースではありません(Unity 4.x に由来しています)が、これらを使用したシェーダーは、低性能ハードウェアでより高速にレンダリングできることがあります。

オプションのパラメーター

Transparency and alpha testing is controlled by alpha and alphatest directives. Transparency can typically be of two kinds: traditional alpha blending (used for fading objects out) or more physically plausible “premultiplied blending” (which allows semitransparent surfaces to retain proper specular reflections). Enabling semitransparency makes the generated surface shader code contain blending commands; whereas enabling alpha cutout will do a fragment discard in the generated pixel shader, based on the given variable.

  • alphaalpha:auto - 単純なライティング機能のために透明度のフェードイン/アウトを選択し (alpha:fade と同様)、物理基盤のライティング関数のために前もって乗算された透明度を選択します (alpha:premul と同様)。
  • alpha:blend - アルファブレンディングを可能にします。
  • alpha:fade - 従来の透過性のフェードイン/アウトを可能にします。
  • alpha:premul - プレマルチプライドアルファ透明度を可能にします。
  • alphatest:VariableName - アルファカットアウト透明度を有効にします。カットオフ値は VariableName をともなう float 変数で示されます。たいてい、addshadow ディレクティブを使用して、適切なシャドウキャスターパスの生成も必用になります。
  • keepalpha - デフォルトでは、出力構造体の Alpha が何であろうと、ライティング関数で何か戻り値であろうと、不透明サーフェスシェーダーは、1.0 (白) をアルファチャネルに書き込みます。このオプションを選択することにより、ライティング関数のアルファ値を不透明サーフェスシェーダーのために、一定に保つことができます。
  • decal:add - 追加的なデカールシェーダー (terrain AddPass など)。他のサーフェスの一番上にあるオブジェクトに有用で、追加的ブレンディングに使用します。サーフェイスシェーダーの例を参照してください。
  • decal:blend - 半透明デカールシェーダー。これは、他のサーフェスの一番上にあるオブジェクトに有用で、アルファブレンディングに使用します。サーフェイスシェーダーの例を参照してください。

Custom modifier functions can be used to alter or compute incoming vertex data, or to alter final computed fragment color.

  • vertex:VertexFunction - カスタム頂点修正関数。この関数は、頂点シェーダーの作成の開始時に呼び出され、頂点データごとに修正や計算を行うことができます。サーフェイスシェーダーの例を参照してください。
  • finalcolor:ColorFunction - カスタムの最終色モディファイア。詳しくは サーフェイスシェーダーの例 を参照してください。
  • finalgbuffer:ColorFunction - GBuffer コンテンツを変更するカスタム deferred パス。
  • finalprepass:ColorFunction - カスタム Prepass Base パス。

シャドウとテッセレーション - シャドウとテッセレーションの取り扱いを制御する追加ディレクティブ。

  • addshadow - シャドウキャスタやコレクタパスを追加します。通常、カスタム頂点編集で使用されるので、シャドウキャスティングも手続き的頂点アニメーションを取得します。多くの場合、シェーダーはフォールバックからシャドウキャスターパスを使用することができるため、特別なシャドウの処理を行う必要はありません。
  • fullforwardshadows - フォワード レンダリングパスで、すべてのライトシャドウをサポートします。デフォルトでは、フォワードレンダリングで、シェーダーは一方向からのシャドウしかサポートしません (内部シェーダー変数の数を節約するため)。フォワードレンダリングでポイントかスポットライトが必要な場合は、このディレクティブを使用します。
  • tessellate:TessFunction - DX11 GPU テッセレーションを使います。詳しくは DX11 / OpenGL コアテッセレーションのサーフェースシェーダーを参照してください。

Code generation options - by default generated surface shader code tries to handle all possible lighting/shadowing/lightmap scenarios. However in some cases you know you won’t need some of them, and it is possible to adjust generated code to skip them. This can result in smaller shaders that are faster to load.

  • exclude_path:deferredexclude_path:forwardexclude_path:prepass - 指定されたレンダリングパスのパスを生成しません (それぞれ、Deferred Shading レンダリングパスForward Rendering パスの詳細旧 Deferred Lighting レンダリングパスを参照してください)。
  • noshadow - このシェーダーでシャドウのサポートを無効にします。
  • noambient - アンビエントライトやライトプローブを適用しません。
  • novertexlights - Forward レンダリングで、ライトプローブや頂点ごとのライトを適用しません。
  • nolightmap - このシェーダーでライトマップのサポートを無効にします。
  • nodynlightmap - このシェーダーでランタイムのダイナミックなグローバルイルミネーションのサポートを無効にします。
  • nodirlightmap - このシェーダーでディレクショナルライトマップを無効にします。
  • nofog - このシェーダーで、すべてのビルトインフォグのサポートを無効にします。
  • nometa - 「メタ」パスを生成しないようにします。 (サーフェス情報を取り出すために、ライトマッピングと動的グローバルイルミネーションに使用します)。
  • noforwardadd - Forward レンダリング追加パスを無効にします。これにより、シェーダーは完全なディレクショナルライトサポートし、その他すべてのライトは、頂点ごと/SH で計算されます。シェーダーもより小さくなります。
  • nolppv - シェーダーのライトプローブプロキシボリュームを無効にします。

その他のオプション

  • softvegetation - Soft Vegetation をオンにすると、サーフェスシェーダーのみがレンダリングされます。
  • interpolateview - ビュー方向をピクセルシェーダーで計算する代わりに、頂点シェーダーで計算して補間します。これにより、ピクセルシェーダーがより早くなりますが、テクスチャ Interpolator を 1 つ使用してしまいます。
  • halfasview - 半分方向のベクトルを、ビュー方向ではなく m ライティング関数に渡します。半距離は頂点ごとに計算、標準化されます。これはより高速ですが、全体的に正しくりません。
  • approxview - Unity 5.0 で廃止されました。interpolateview を代わりに使用してください。
  • dualforward - Forward レンダリングパスで、グローバルイルミネーション を使用します。

上記のさまざまなオプションが実際、それぞれどのように違うのかを見るには、Shader Inspectorの “Show Generated Code” ボタンを使用すると便利です。

サーフェスシェーダーの input 構造体

入力の構造体 Input には一般に、シェーダーによって必要とされるテクスチャ座標があります。テクスチャ座標の名前は、uv の後にテクスチャ名が来る形にする必要があります (第 2 のテクスチャ座標セットを使用するには、uv2 で始めます)。

以下の値が入力構造に入力できます。

  • float3 viewDir - ビュー方向を含みます。視差効果、リムライティングなどの計算に使用されます。
  • float4 with COLOR セマンティック - 補間された頂点ごとの色を含みます。
  • float4 screenPos - 反射、または、スクリーンスペースエフェクトのためのスクリーンスペース位置を含みます。これは、GrabPass には適していないので注意してください。GrabPass のためにはComputeGrabScreenPos 関数でカスタム UV を算出する必要があります。
  • float3 worldPos - ワールド空間の位置を含みます。
  • float3 worldRefl - サーフェスシェーダーが o.Normal に書き込まない場合 のワールドの反射ベクトルを含みます。例については、反射―デフューズシェーダーを参照してください。
  • float3 worldNormal - サーフェスシェーダーが o.Normal に書き込まない場合 のワールドの法線ベクトルを含みます。
  • float3 worldRefl; INTERNAL_DATA - サーフェスシェーダーが o.Normal に書き込む場合 のワールドの反射ベクトルを含みます。ピクセル法線マップに基づいて反射ベクトルを取得するには、WorldReflectionVector (IN, o.Normal) を使用します。例については、反射-Bumped シェーダーを参照してください。
  • float3 worldNormal; INTERNAL_DATA - サーフェスシェーダーが o.Normal に書き込む場合 のワールドの反射ベクトルを含みます。ピクセル法線マップに基づいて法線ベクトルを取得するには、WorldNormalVector (IN, o.Normal) を使用します。

サーフェイスシェーダーと DirectX 11 HLSL 構文

現在サーフェイスシェーダーの一部のコンパイルパイプラインは DirectX 11 特有の HLSL 文法を解釈できないため、もし StructuredBuffers、RWTextures およびその他の非 DX9 文法といった HLSL 機能を使用する場合は、DX11 のみのプリプロセッサーマクロでラッピングする必要があります。

詳しくは、プラットフォーム別のレンダリングの違いUnity で使用するシェーダー言語を参照してください。

シェーダーリファレンス
サーフェイスシェーダーの例