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

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

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

Surface Shaders in Unity is a code generation approach that makes it much easier to write lit shaders than using low level vertex/pixel shader programs. Note that there are no custom languages, magic or ninjas involved in Surface Shaders; it just generates all the repetitive code that would have to be written by hand. You still write shader code in HLSL.

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

どのように機能するか

You define a “surface function” that takes any UVs or data you need as input, and fills in output structure SurfaceOutput. SurfaceOutput basically describes properties of the surface (it’s albedo color, normal, emission, specularity etc.). You write this code in HLSL.

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

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

struct SurfaceOutput
{
    fixed3 Albedo;  // diffuse color
    fixed3 Normal;  // tangent space normal, if written
    fixed3 Emission;
    half Specular;  // specular power in 0..1 range
    fixed Gloss;    // specular intensity
    fixed Alpha;    // alpha for transparencies
};

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

struct SurfaceOutputStandard
{
    fixed3 Albedo;      // base (diffuse or specular) color
    fixed3 Normal;      // tangent space normal, if written
    half3 Emission;
    half Metallic;      // 0=non-metal, 1=metal
    half Smoothness;    // 0=rough, 1=smooth
    half Occlusion;     // occlusion (default 1)
    fixed Alpha;        // alpha for transparencies
};
struct SurfaceOutputStandardSpecular
{
    fixed3 Albedo;      // diffuse color
    fixed3 Specular;    // specular color
    fixed3 Normal;      // tangent space normal, if written
    half3 Emission;
    half Smoothness;    // 0=rough, 1=smooth
    half Occlusion;     // occlusion (default 1)
    fixed Alpha;        // alpha for transparencies
};

サンプル

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

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

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

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

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

#pragma surface surfaceFunction lightModel [optionalparams]

必要なパラメーター

  • surfaceFunction - which Cg function has surface shader code. The function should have the form of void surf (Input IN, inout SurfaceOutput o), where Input is a structure you have defined. Input should contain any texture coordinates and extra automatic variables needed by surface function.
  • lightModel - lighting model to use. Built-in ones are physically based Standard and StandardSpecular, as well as simple non-physically based Lambert (diffuse) and BlinnPhong (specular). See Custom Lighting Models page for how to write your own.
    • ライティングモデル 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 - Disables Light Probe Proxy Volume support in this shader.
  • noshadowmask - Disables Shadowmask support for this shader (both Shadowmask and Distance Shadowmask).

その他のオプション

  • softvegetation - Soft Vegetation をオンにすると、サーフェスシェーダーのみがレンダリングされます。
  • interpolateview - ビュー方向をピクセルシェーダーで計算する代わりに、頂点シェーダーで計算して補間します。これにより、ピクセルシェーダーがより早くなりますが、テクスチャ Interpolator を 1つ使用してしまいます。
  • halfasview - 半分方向のベクトルを、ビュー方向ではなく m ライティング関数に渡します。半距離は頂点ごとに計算、標準化されます。これはより高速ですが、全体的に正しくりません。
  • approxview - Unity 5.0 で廃止されました。interpolateview を代わりに使用してください。
  • dualforward - Forward レンダリングパスで、グローバルイルミネーション を使用します。
  • dithercrossfade - Makes the surface shader support dithering effects. You can then apply this shader to GameObjects that use an LOD Group component configured for cross-fade transition mode.

上記のさまざまなオプションが実際、それぞれどのように違うのかを見るには、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で使用するシェーダー言語を参照してください。


  • 2017–06–08 限られた 編集レビュー でパブリッシュされたページ

  • noshadowmask added in 5.6

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