読者です 読者をやめる 読者になる 読者になる

ゆにてく備忘録

Unityやその他学んだ事を忘れないために書くぶろぐ

Unity Shader まとめ

Shader Unity

自分用にいろいろなサイトからshaderの基本的なことをまとめました。

はじめに

unityのshderは3種類ある

  • Fixed Function Shaders (固定機能シェーダ)
  • Surface Shaders (サーフェイスシェーダ)
  • Vertex and Fragment Shaders (頂点/フラグメントシェーダ)

 

ShaderLabの構造

上の三種類をShader Lab という枠組みで記述する。
Shader Labは以下のような構造をしている。

Shader "MyShader" {
    Properties {
        _MyTexture ("My Texture", 2D) = "white" { }
        // カラーやベクトルなどのプロパティもこの箇所に記述
    }
    SubShader {
        // この箇所に以下の本体を記述
        //  - サーフェイスシェーダ または
        //  - 頂点およびフラグメントシェーダ または
        //  - 固定関数シェーダ
    }
    SubShader {
        // この箇所に、古いグラフィックスカードで実行される、より簡易のバージョンの前述のサブシェーダを記述
    }
}

シェーダは、複数の SubShaders を含むことができ、ハードウェアがサポートする最初のサブシェーダを使用する。
各サブシェーダは、パスの集合であり、各パスに対して、オブジェクトがレンダリングされるため、少なくとも 1 つのパスが必要となる。詳細はShader Labのところで書く。

Fixed Function Shaders (固定機能シェーダ)

固定関数シェーダは、古いハードウェアのために記述する必要があります。固定関数シェーダはフラグメントシェーダまたはサーフェイスシェーダの後の n 番目の fallback として記述して、古いハードウェアで実行したときもレンダリングを行えるようにします。固定関数シェーダはすべて ShaderLab で書かれます
( referenceより)

固定機能 (fixed function) シェーダは今回は省略。 <固定機能シェーダ例>

参考URL

Surface Shaders (サーフェイスシェーダ)

Surface Shaders は もしシェーダがライトおよびシャドウの影響を受ける場合に使います。
もしシェーダがライトで何もしない場合は、非常にたくさんのライティング計算を行うことになるのでサーフェイス シェーダを使用すべきでない。 Surface Shaders はSub Shaderの中で記述される。

Shader "Custom/SurfaceShader1" {
 Properties {
  _MainTex ("Base (RGB)", 2D) = "white" {}
 }
 SubShader {
  CGPROGRAM
  #pragma surface surf Lambert

  sampler2D _MainTex;

  struct Input {
   float2 uv_MainTex;
  };

  void surf (Input IN, inout SurfaceOutput o) {
   half4 c = tex2D (_MainTex, IN.uv_MainTex);
   o.Albedo = c.rgb;
   o.Alpha = c.a;
  }
  ENDCG
 }
 FallBack "Diffuse"
}

上のシェーダはテクスチャを貼付けるだけのshaderです。一つずつ説明していく。

プロパティ(少しだけ)

 Properties {
  _MainTex ("Base (RGB)", 2D) = "white" {}
 }

インスペクタから使用するテクスチャを選択するための記述。ほかにも値など様々なものを設定できる。
詳細はShader Labのところで書く

CGPROGRAM

CGPROGRAM
.....
ENDCG

Cg言語でこれから記述していきますよという意味。この中ではCg言語の関数や変数を使う。いつか変数とか関数とかまとめるかも。とりあえず Cg言語のリファレンスへのリンク

サーフェスシェーダ宣言

#pragma surface surf Lambert

このサブシェーダーがサーフェイスシェーダであることを知らせるために必要な宣言です。
構造は #pragma surface surfaceFunction lightModel [optionalparams] の様になっています。

surfaceFunctionの部分にはCg で記述されたSurface Shader の関数(surface 関数)の名前を指定します。
上の例では、void surf (Input IN、inout SurfaceOutput o) というsurface関数を持つことを意味します。ここのInputは定義しなければならない構造体になります。

lightModelは使用するライティング モデルを表します。 Lambert (デフューズ) と BlinnPhong (スペキュラ) のどちらかを選ぶことができます。また自分でライティングモデルを記述してカスタムライテリングモデルを作った場合にはそれを指定することもできます。詳細はいつか書くかも...とりあえず 参考リンク

optionalparamsにはオプションを設定できます。 設定できるオプションは以下(unityの リファレンスマニュアルより)

alpha
- アルファ ブレンディング モード。 半透明のシェーダに使用します。
alphatest:VariableName
- アルファ テスト モード。 透明カットアウトシェーダに使用します。 カットオフ値は、変数名がVariableName のfloat 値になります。
vertex:VertexFunction
- カスタムの頂点編集関数。 例については、Tree Barkシェーダを参照。
finalcolor:ColorFunction
- カスタムの最終色モディファイア。詳しくは Surface Shader Examplesを参照して下さい。
exclude_path:prepass< or exclude_path:forward
- 所定のレンダリング パスにパスを生成しません。
addshadow
- シャドウ キャスタおよびコレクタ パスを追加します。 通常、カスタム頂点編集で使用されるので、シャドウ キャスティングも手続き的頂点アニメーションを取得します。
dualforward
- forwardレンダリング パスで、 dual lightmapsを使用します。
fullforwardshadows
- Forwardレンダリング パスで、すべてのタイプのシャドウをサポートします。
decal:add
- 追加のデカール シェーダ (例: 地形 AddPass)。
decal:blend
- 半透明のデカール シェーダ。
softvegetation
- Soft Vegetation をオンにすると、Surface Shaderのみレンダリングするようにします。
noambient
- アンビエントや球面調和関数ライトを適用しません。
novertexlights
- Forward レンダリングで、球面調和関数または頂点ごとのライトを適用しません。
nolightmap
- このシェーダでライトマップのサポートを無効にします(シェーダをより小さくします)。
nodirlightmap
- このシェーダでディレクショナルライトマップを向こうにします(シェーダをより小さくします)。
noforwardadd
- Forwardレンダリング追加パスを無効にします。 これにより、シェーダは完全なディレクショナル ライトサポートし、その他すべてのライトは、頂点ごと/SH で計算されます。シェーダもより小さくなります。
approxview
- 標準化されたビュー方向をピクセルごとではなく、頂点ごとに計算します。これを必要としているシェーダに行われます。 これは、より速いですが、カメラが表面に近づくと、ビュー方向は全体的に正しくありません。
halfasview
- 半分方向のベクトルを、ビュー方向ではなくmライティング関数に渡します。 半距離は頂点ごとに計算および標準化されます。 これはより高速ですが、全体的に正しくりません。
tessellate:TessFunction
- DX11 GPUテッセレーションを使います。詳しくは Surface Shader Tessellationをご覧ください。
#pragma surface surf Lambert alpha

もし半透明なシェーダを作りたいのなら、以上の様に宣言する。

プロパティへの参照

sampler2D _MainTex;

Propertiesで宣言したテクスチャや値を使用する場合、Propertiesで宣言した名前と同じ名前でSubShaderの中で宣言しなければならない。詳細リンク(下の記事)

Input構造体

  struct Input {
   float2 uv_MainTex;
  };

ここでsurface 関数の引数となるInput構造体を宣言している。surface 関数でテクスチャ座標が必要ならば、Input 構造体でテクスチャ座標を代入する変数を宣言しなければならない。 テクスチャ座標を代入する変数の名前をPropertiesで宣言したテクスチャの名前の前にuvをつけたものとすることで、自動的にテクスチャ座標が代入される。(第 2 のテクスチャ座標セットを使用するには、uv2で始める)。

また以下のものをInput構造体の中で宣言することで、surface関数で使用できます。(unityの リファレンスマニュアルより)

float3 viewDir
- ビュー方向を含みます。視差効果、リム ライティングなどの計算に使用されます。
float4 with COLOR
セマンティック - 補間された頂点ごとの色を含みます。
float4 screenPos
- 反射効果の画面空間位置を含みます。 例えば、Dark Unity では、WetStreet シェーダによって使用されます。
float3 worldPos
- 世界空間の位置を含みます。
float3 worldRefl
- Surface Shaderが o.Normal に書き込まない場合の世界反射ベクトルを含みます。 例については、反射 - デフューズ シェーダを参照。
float3 worldNormal
- Surface Shaderが o.Normal に書き込まない場合の世界法線ベクトルを含みます。
float3 worldRefl; INTERNAL_DATA
- Surface Shaderが o.Normal に書き込む場合の世界反射ベクトルを含みます。 ピクセルごとの法線マップに基づいて、反射ベクトルを取得するには、 WorldReflectionVector (IN, o.Normal)を使用します。 例については、反射 - バンプ型 シェーダを参照。
float3 worldNormal; INTERNAL_DATA
- Surface Shaderが o.Normal に書き込む場合の世界反射ベクトルを含みます。 ピクセルごとの法線マップに基づいて、法線ベクトルを取得するには、 WorldNormalVector (IN, o.Normal)を使用します。
  struct Input {
   float2 uv_MainTex;
   float3 worldPos;
  };

もしシェーダーでワールド座標とテクスチャ座標を使うならば、以上の様にInput構造体を宣言する。

サーフェス関数

  void surf (Input IN, inout SurfaceOutput o) {
   half4 c = tex2D (_MainTex, IN.uv_MainTex);
   o.Albedo = c.rgb;
   o.Alpha = c.a;
  }

surface 関数の記述。Input構造体の値や、Propertiesで宣言したテクスチャや値の変数を用いて処理を行い、その結果をこの関数の第2匹数である inout SurfaceOutput o に代入することにより、シェーダの処理を行う。

struct SurfaceOutput {
    half3 Albedo;    // 拡散反射光(=Diffuse)
    half3 Normal;    // 法線ベクトル
    half3 Emission;  // エミッション
    half Specular;   // スペキュラ
    half Gloss;      // 輝き
    half Alpha;      // 透過度
};

SurfaceOutputは上のような構造をしている。
上の例の16行目でCg言語のtex2D()関数を使用してRGBA カラーを変数cに代入している。17、18行目でテクスチャの色とアルファ値を代入している。

FallBack

 FallBack "Diffuse"

Sub Shaderがハードウェアの影響で割り当てられなかった場合に、組み込みシェーダの一つであるdiffuseシェーダーを呼び出すための一文。 FallBack詳細

テッセレーション

テッセレーションについては省略。 参考リンク

Vertex and Fragment Shaders (頂点/フラグメントシェーダ)

もしシェーダがライティングする必要がない、またはサーフェイス シェーダでは表現できないエフェクトである場合、頂点およびフラグメントシェーダは必要となる。頂点処理、ピクセル処理を記述するシェーダーである。 基本的な構造は以下である。

Shader "Custom/SolidColor" {
    SubShader {
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            float4 vert(float4 v:POSITION) : SV_POSITION {
                return mul (UNITY_MATRIX_MVP, v);
            }
            fixed4 frag() : COLOR {
                return fixed4(1.0,0.0,0.0,1.0);
            }
            ENDCG
        }
    }
}

上のシェーダは赤くするだけのshaderです。一つずつ説明していく

頂点シェーダ宣言

#pragma vertex vert

これサーフェスシェーダの時と同様に、これから頂点シェーダ関数を記述しますということを表す。この例ではvertが関数名。

フラグメントシェーダ宣言

#pragma fragment frag

これからフラグメントシェーダを記述することを表している。fragが関数名。

基本的に頂点シェーダ関数とフラグメントシェーダ関数で、頂点/フラグメントシェーダはできている。これ以外のほかの関数も記述できる。
またこのシェーダを実行するターゲットも指定できる。ターゲットによって使える機能が変わるので、指定しなければエラーとなることがある(WPOSセマンティクスなど)ほかの関数とターゲットについての詳細リンク

頂点シェーダ関数

            float4 vert(float4 v:POSITION) : SV_POSITION {
                return mul (UNITY_MATRIX_MVP, v);
            }

頂点ごとに実行される頂点シェーダ関数である。頂点シェーダ関数では戻り値に頂点座標となるfloat4型の値もしくは、これを含む構造体を指定しなければならない。戻り値はSV_POSITIONもしくはPOSITIONはセマンティックを指定しなければならない。ここでは、: SV_POSITIONと書くことで、戻り値をSV_POSITIONセマンティクスにバインドしている。UNITY_MATRIX_MVPはモデル変換、ビュー変換、投影変換をかけ算した行列でそれに、頂点座標vをかけることで、カメラ座標系での頂点位置を計算している。

引数には以下のもの、もしくは値を指定できます。複数指定する場合は構造体にするとよい。引数はセマンティクスでバインドしなければならない

float4 vertex
ー モデルのローカル頂点座標。セマンティクスはPOSITION
float3 normal
ー 頂点の法線。セマンティクスはNORMAL
float4 texcoord
ー 1つ目の UV座標セマンティクスはTEXCOORD0
float4 texcoord1
ー 2つ目の UV座標セマンティクスはTEXCOORD1
float4 tangent
ー 接線ベクトル(法線マッピングに使用されます)。セマンティクスはTANGENT
float4 color
ー 頂点ごとの色セマンティクスはCOLOR


戻り値には以下のもの、もしくは値を指定できる。この戻り値で指定したものをフラグメントシェーダ関数の引数として渡せる。

float4 position
ー MVP 変換後の座標。セマンティクスはSV_POSITION
float3 normal
ー MVP 変換後のの法線。セマンティクスはNORMAL
float4 texcoord
ー 1つ目の UV座標セマンティクスはTEXCOORD0
float4 texcoord1
ー 2つ目の UV座標セマンティクスはTEXCOORD1
float4 tangent
ー 接線ベクトル(法線マッピングに使用されます)。セマンティクスはTANGENT
float4 or fixed4 color
ー 線形補間された色。セマンティクスはCOLOR0
float4 or fixed4 color
ー 線形補間された色。セマンティクスはCOLOR1
    • セマンティクスを持たない何らかの変数。


頂点座標の引数には #include "UnityCG.cginc" の一文をPASSの中に書くことで、よく使う以下の構造体やシェーダを使用できる。使い方は以下

float4 vert(appdata_base v) : POSITION {
    return mul (UNITY_MATRIX_MVP, v.vertex);
   }


使える構造体は以下

struct appdata_base {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
};
 
struct appdata_tan {
    float4 vertex : POSITION;
    float4 tangent : TANGENT;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
};
 
struct appdata_full {
    float4 vertex : POSITION;
    float4 tangent : TANGENT;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
    float4 texcoord1 : TEXCOORD1;
    fixed4 color : COLOR;
#if defined(SHADER_API_XBOX360)
 half4 texcoord2 : TEXCOORD2;
 half4 texcoord3 : TEXCOORD3;
 half4 texcoord4 : TEXCOORD4;
 half4 texcoord5 : TEXCOORD5;
#endif
};

 

フラグメントシェーダ関数

            fixed4 frag() : COLOR {
                return fixed4(1.0,0.0,0.0,1.0);
            }

ピクセル毎に実行されるフラグメントシェーダ関数である。フラグメントシェーダ関数では戻り値に色となるfloat4型の値もしくは、fixed4型を指定しなければならない。戻り値は :COLORセマンティックを指定しなければならない。ここでは、 : COLORと書くことで、戻り値をCOLORセマンティクスにバインドしている。戻り値にfixed4(1.0,0.0,0.0,1.0)を指定して、赤く塗っている

また#pragma target 3.0をPASSで指定することで、WPOSセマンティクスをつけた引数を持たせることができる。この引数にはスクリーン座標が代入されている。

プロパティで宣言した変数へのアクセスについて


もしプロパティ内で以下のように宣言したとする。

_MyColor ("Some Color", Color) = (1,1,1,1)
_MyVector ("Some Vector", Vector) = (0,0,0,0)
_MyFloat ("My float", Float) = 0.5
_MyTexture ("Texture", 2D) = "white" {}
_MyCubemap ("Cubemap", CUBE) = "" {}

このとき、これらのプロパティにアクセスするためには以下のように変数を宣言しなければならない。

fixed4 _MyColor; // low precision type is enough for colors
float4 _MyVector;
float _MyFloat;
sampler2D _MyTexture;
samplerCUBE _MyCubemap;

 

  • ColorとVectorプロパティは、 float4half4あるいは fixed4変数に対応
  • RangeとFloatプロパティは、 floathalfあるいは fixed変数に対応
  • Textureプロパティは、通常(2D)のテクスチャの場合は sampler2D変数に対応、3Dテクスチャの場合は sampler3D変数に対応

参考リンク

インクルードファイルについて(特にUnityCG.cginc)


ファイルをインクルードすることで、定義済み変数やヘルパー関数を利用できる。以下のように宣言する。

CGPROGRAM
    // ...
    #include "UnityCG.cginc"
    // ...
    ENDCG



内蔵インクルードファイルには以下のものがある。

HLSLSupport.cginc
- (自動でインクルード)ヘルパーマクロやクロスプラットフォームのシェーダコンパイルの定義
UnityCG.cginc
- 一般に使用されるグローバル変数やヘルパー関数。
AutoLight.cginc
- ライティングやシャドウ機能、すなわち surface shadersは内部的にこのファイルを使用します。
Lighting.cginc
- 標準的な surface shaderライティングモデル、サーフェイスシェーダを記述するとき自動的にインクルードされます。
TerrainEngine.cginc
- Terrain(地形)やVegetation(植生)のシェーダのヘルパー関数。
HLSLSupport.cginc
- このファイルはシェーダをコンパイルする際に 自動でインクルードされます。マルチプラットフォームのシェーダ開発を手助けするため、様々な preprocessor macrosを定義します。

これらのコードはUnityアプリケーションの(Windowsでは{unity install path}/Data/CGIncludes/UnityCG.cginc 、Macでは/Applications/Unity/Unity.app/Contents/CGIncludes/UnityCG.cginc )にある。

UnityCG.cginc

構造体

struct appdata_base {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
};
 
struct appdata_tan {
    float4 vertex : POSITION;
    float4 tangent : TANGENT;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
};
 
struct appdata_full {
    float4 vertex : POSITION;
    float4 tangent : TANGENT;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
    float4 texcoord1 : TEXCOORD1;
    fixed4 color : COLOR;
//texcoord2~5まであるけど長くなるから省略
};



汎用的関数

float3 WorldSpaceViewDir (float4 v)
- ワールド空間の、特定のオブジェクト空間の頂点位置からカメラに向かった、(正規化されていない)方向。
float3 ObjSpaceViewDir (float4 v)
- オブジェクト空間の、特定のオブジェクト空間の頂点位置からカメラに向かった、(正規化されていない)方向。
float2 ParallaxOffset (half h, half height, half3 viewDir)
- 視差法線マッピングのUVオフセットを計算。
fixed Luminance (fixed3 c)
- 色を輝度(グレースケール)に変換します
fixed3 DebLightmap (fixed4 color)
- Unityライトマップの色をデコードします(プラットフォームにより、RGBMあるいはdLDR)
float4 EnbFloatRGBA (float v)
- 精度の低いレンダリングターゲットを格納するため、0~1の範囲の浮動小数点をRGBAcolorにエンコードします。
float DebFloatRGBA (float4 enc)
- RGBA colorをfloatにデコードします。
    • 上記と同様ですが、
float2 EnbFloatRG (float v) および float DebFloatRG (float2 enc)
は二つのカラーチャネルを使用します。
float2 EnbViewNormalStereo (float3 n)
- ビュー空間法線を0~1の範囲の二つの数字にエンコードします。
float3 DebViewNormalStereo (float4 enc4)
- enc4.xyからビュー空間法線をデコードします。



Forward Render用関数

float3 WorldSpaceLightDir (float4 v)
- ワールド空間の、オブジェクト空間の頂点位置からライトへ向けた、(正規化されてない)方向を計算します
float3 ObjSpaceLightDir (float4 v)
- オブジェクト空間の、オブジェクト空間の頂点位置からライトへ向けた、(正規化されてない)方向を計算します
float3 Shade4PointLights (...)
- 四つのポイントライトから、ライトのデータをvectorに格納して、輝度を算出します。Forward Renderingは各頂点ごとのライティングにこの情報を使用します。



頂点ライティングシェーダ用関数

float3 ShadeVertexLights (float4 vertex, float3 normal)
- 4つの各頂点ライトから、オブジェクト空間の位置と法線を指定して、輝度と環境光を算出します。

 

組み込み変数、行列について


Programmable Shaders で使用する場合は UnityCG.cginc file をインクルードする必要があります。

変換行列

float4x4 UNITY_MATRIX_MVP
現在のモデルビュー行列×射影行列(model*view*projection)
float4x4 UNITY_MATRIX_MV
現在のモデルビュー行列
float4x4 UNITY_MATRIX_V
現在のビュー行列
float4x4 UNITY_MATRIX_P
現在の投影行列
float4x4 UNITY_MATRIX_VP
現在のビュー行列×射影行列
float4x4 UNITY_MATRIX_T_MV
モデルビュー行列の転置行列
float4x4 UNITY_MATRIX_IT_MV
モデルビュー行列の逆行列の転置行列
float4x4 UNITY_MATRIX_TEXTURE0 to UNITY_MATRIX_TEXTURE3
テクスチャの転置行列
float4x4 _Object2World
現在のモデル行列
float4x4 _World2Object
現在のモデル行列の逆行列
float3 _WorldSpaceCameraPos
ワールド座標系のカメラの位置
float4 unity_Scale
xyzコンポーネントを使用せず、 .wが均一に拡大・縮小するスケールを保持しています
float4 UNITY_LIGHTMODEL_AMBIENT
現在の周辺色。



ライティング

float4x4 UNITY_MATRIX_MVP
現在のモデルビュー行列×射影行列(model*view*projection)
float4 _ModelLightColor
マテリアルのModel×Light color。
float4 _SpecularLightColor
マテリアルのSpecular×Light color。
float4 _ObjectSpaceLightPos
オブジェクト座標系でのライトの位置。wコンポーネントが 0 の場合は指向性ライト、1 の場合はその他のライト。
float4x4 _Light2World
ライトからワールド座標系の行列。
float4x4 _World2Light
ワールドからライト座標系の行列。
float4x4 _Object2Light
オブジェクトからライト座標系の行列。

Cgプログラムの外では、名前の末尾に0、Cgプログラムの中では、配列として参照できる。_ModelLightColorは前者では_ModelLightColor0、後者では_ModelLightColor[0]でアクセスできる。

その他

float4 _Time
時間 (t/20、t、t×2、t×3)、シェーダの中でアニメーションするのに使用。
float4 _SinTime
時間のサイン関数: (t/8、t/4、t/2、t)、左から順に(_SinTime.x,_SinTime.y,_SinTime.z,_SinTime.w)
float4 _CosTime
時間のコサイン関数: (t/8、t/4、t/2、t)、左から順に(_CosTime.x,_CosTime.y,_CosTime.z,_CosTime.w)
float4 unity_DeltaTime
デルタ時間: (dt、1/dt、smoothDt、1/smoothDt)
float4 _ProjectionParams
xは 1.0 または -1.0、反転した射影行列で現在レンダリングしている場合は負の値。
yは カメラのNear Plane
zは カメラのFar Plane
wは 1/Far Plane。
float4 _ScreenParams
xは 現在のレンダリングターゲットのピクセル幅
yは 現在のレンダリングターゲットのピクセル高さ
zは 1.0 + 1.0/幅
wは 1.0 + 1.0/高さ

 

Shader Labについて


UnityのシェーダはShader Labという枠組みで記述される。構造は以下の様になっている

Shader "MyShader" {
    Properties {
        ....
    }
    SubShader {
        PASS{
            ....
        }
    }
    SubShader {
        PASS{
            ....
        }
    }
    FallBack ....
}

Properties、SubShader、FallBackで構成される。SubShaderはいくつものPASSで構成される。SubShaderを上から一つずつ見て、ハードウェアに合うSubShaderで実行される。FallBackは何らかの実行をするために呼び出されるシェーダを指定する。

Properties(プロパティ)

プロパティは以下のものがある。

name("display name", Range( min, max)) = number
floatプロパティを定義し、インスペクタ上でスライドバーが minから maxとして表現。
name("display name", Color) = ( number, number, number, number)
colorプロパティを定義。
name("display name", 2D) = "name" { options}
2Dテクスチャプロパティを定義。
name("display name", Rect) = "name" { options}
長方形(2のべき乗でない)テクスチャのプロパティを定義。
name("display name", Cube) = "name" { options}
キューブマップテクスチャのプロパティを定義。
name("display name", Float) = number
floatプロパティを定義
name("display name", Vector) = ( number, number, number, number)
4コンポーネント ベクトルのプロパティを定義。



具体的には以下のように指定する。

Properties {
    _Rabge( "Range", Range(0.0, 1.0) ) = 0.5          //スライドバー
    _Color ("Color", Color) = (0.5, 1.0, 0.1, 0.7)    //カラーピッカー
    _Tex ("Tex2D", 2D) = "white" {}                   //texture選択、tiling、offset
    _TexRect ("TexRect", Rect) = "white" {}           //texture選択、tiling、offset
    _TexCube ("TexCube", Cube) = "white" {}           //texture選択、tiling、offset
    _Float("Float", Float) = 20.0                     //値代入
    _Vector("Vector", Vector) = (0.5, 0.7, 0.2, 0.4)  //(X、Y、Z、W)の値代入
}

Texture3種類の代入する文字列には、空の文字列か内蔵のデフォルトテクスチャ: "white" 、"black" 、"gray" 、"bump" を指定する。 Texture3種類の{}の中のオプションには

  • TexGen texgenmode
  • LightmapMode

が指定できる。texgenmodeには

  • ObjectLinear
  • EyeLinear
  • SphereMap
  • CubeReflect
  • CubeNormal

が指定できる。これらはOpenGL texgenモードと直接に対応する。texgenモードはテクスチャ座標の設定ができる。しかし頂点プログラムが定義されている場合は無視されるので固定機能シェーダでしか使えない。ObjectLinearと EyeLinearの違いはここの リンクへ。LightmapModeタグは何も行われなくなった。これはLegacy Shaderとかで使われてたやつで別のuv座標を使うのに使われてたのかな?

Subshaders(サブシェーダー)

サブシェーダーは任意個のパスとサブシェーダータグを記述する。一つのパスに対して一回レンダリングするので、処理を軽くするためにパスは最小個数におさえた方がよい。各パスの定義はregular PassUse Pass 、またはGrab Pass のいずれかでできる。パスには様々なレンダリング設定(State)を定義することができ、パスブロックの中にStateを書くとパスブロックの中でのみStateは有効となり、パスブロックの外のサブシェーダーブロックに書くとすべてのパスに共通するStateを定義することができる。

SubShader {
        Tags {
                "Queue" = "Transparent"
                "RenderType" = "Opaque"
                "IgnoreProjector" = "True"
        }
        LOD 100   //すべてのパスに共通するState
        Pass {
                Lighting Off    //このパスに共通するState
                ...
        }
        Pass {
                Lighting On    //このパスに共通するState
                ...
        }
}

パス(PASS)

パスにはName、パスTags(サブシェーダータグとは別)、レンダリング設定(State)、テクスチャ設定、BindChannels、ステンシルを記述できる。

Name

パスに名前を付けることで、他のshaderから名前をつけたパスを参照(UsePass)できるようにする。

Name "MyPassName"

パスTags

PASSがいつどのようにしてレンダリングエンジンによりレンダリングすべきかを指定する。このパスがライティング パイプライン(環境光、頂点ライティング、ピクセルライティング)のなかでどの役割であるかを制御したり、他のパラメータを判定するのに使用します。具体的にはLightModeタグとRequireOptionsタグにより指定する。以下が具体例

SubShader {
        Pass {
                Tags { "LightMode" = "ForwardBase" "RequireOptions" = "SoftVegetation"}
                ...
        }
}
1- LightModeタグ

LightModeタグはレンダーパイプライン(リンク)でのパスの役割を決める。サーフェスシェーダーでは自動で生成されている。なのでサーフェスシェーダーを使わずに、自分でカスタマイズしたい場合に指定して使えばいい。使用例1使用例2 以下は使用できるLightModeタグ

  • Always: 常にレンダリングされ、ライティングは適用されません。
  • ForwardBase: Forward rendering で使用され、環境光、メイン指向性ライト、頂点/SHライトが適用されます。
  • ForwardAdd: Forward rendering で使用され、ライトごとに一つのパスで、Additive ピクセルライティングが適用されます。
  • PrepassBase: Deferred Lighting で使用され、法線や鏡面指数をレンダリングします。
  • PrepassFinal: Deferred Lighting で使用され、最終的なカラーについて、テクスチャ、ライト、および自己発光、を合成することでレンダリングします。
  • Vertex: Vertex Lit rendering でオブジェクトがライトマップされてない場合に使用され、全ての頂点ライトが適用されます。
  • VertexLMRGBM: Vertex Lit rendering でオブジェクトがライトマップされてる場合、ライトマップがRGBMエンコードされるプラットフォームにおいて使用されます。
  • VertexLM: Vertex Lit rendering でオブジェクトがライトマップされてる場合に、ライトマップがdoub-LDRエンコードされるプラットフォームにおいて(一般にモバイル向けプラットフォームや古いデスクトップ向けGPUにて)使用されます。
  • ShadowCaster: オブジェクトを、Shadow Casterとしてレンダリングします。
  • ShadowCollector: Forward Renderingのために、オブジェクトの影をScreen-Spaceバッファに集めます。
2- RequireOptionsタグ

特定の外部条件が満たされた場合のみレンダリングされることを、パスで指定することが出来る。 SoftVegetationを指定することで、もしQuality Settings でSoft Vegetationが有効である場合のみ、このパスをレンダリングします。

レンダリング設定(State)

以下のコマンドを指定できる

Material { Material Block }
頂点ライティングのパイプラインでしようするマテリアルを定義します。詳細についてはmaterial page を参照下さい。
Lighting On | Off
頂点ライティングを有効、無効にします。詳細についてはmaterial page を参照下さい。
Cull Back | Front | Off
ポリゴン カリングモードを設定します。
ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always)
デプス テストモードを設定します。
ZWrite On | Off
デプス書き込みモードを設定します。
Fog { Fog Block }
フォグパラメータを設定します。
AlphaTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always) CutoffValue
アルファテストを有効にします。
Blend SourceBlendMode DestBlendMode
アルファ ブレンディング モードを設定します。
Color Color value
頂点ライティングが無効のとき、使用するカラーを設定します。
ColorMask RGB | A | 0 | any combination of R, G, B, A
ColorMask 0と記載することで全てのカラーチャネルのレンダリングを無効化します。
Offset OffsetFactor , OffsetUnits
デプスのオフセットを設定します。Unity3.0以降、このコマンドは意図的に定数(すなわちシェーダパラメータではない)しか設定できないことに留意下さい。
SeparateSpecular On | Off
頂点ライティングの別の鏡面カラーを有効、無効にします。詳細についてはmaterial page を参照下さい。
ColorMaterial AmbientAndDiffuse | Emission
頂点ライティングのときに、各頂点ごとのカラーを使用します。詳細についてはmaterial page を参照下さい。
・Material { Material Block }

マテリアルブロックはオブジェクトのマテリアルプロパティを定義するのに使用します。 Material Block(マテリアルブロック)

Diffuse Color
拡散カラーコンポーネント。オブジェクトのベースカラーです。
Ambient Color
環境光カラーコンポーネント。この色は、オブジェクトが環境光に当たった時にRenderSettings で設定された、オブジェクトが保有する色です.
Specular Color
The color of the object's specular highlight.
Shininess Number
ハイライトのシャープネスで、0から1まで設定できます。0では拡散ライティングに良く似た巨大なハイライトで、1ではわずかな小粒のハイライトです。
Emission Color
オブジェクトが、どのような光にも当てられない場合のオブジェクトのカラー

ここではマテリアルが光に対して反応する方法を設定します。これらのプロパティのどれも必須ではなく、指定しない場合のデフォルト値は黒です(すなわちエフェクトなし)。

Properties {
  _Color ("Main Color", Color) = (1,1,1,0)
  _SpecColor ("Spec Color", Color) = (1,1,1,1)
  _Emission ("Emmisive Color", Color) = (0,0,0,0)
  _Shininess ("Shininess", Range (0.01, 1)) = 0.7
}
SubShader {
  Pass {
    Material {
      Diffuse [_Color]
      Ambient [_Color]
      Shininess [_Shininess]
      Specular [_SpecColor]
      Emission [_Emission]
    }
    Lighting On
    SeparateSpecular On
    SetTexture [_MainTex] {
      Combine texture * primary DOUBLE, texture * primary
    }
  }
}

オブジェクトに当てられたライトのフルカラーは: Ambient * RenderSettings ambient setting + (Light Color * Diffuse + Light Color * Specular) + Emission で計算される.計算式のライト部分(括弧( )内における)は、オブジェクトに当たる全てのライトの分だけ、繰り返される。 通常はDiffuse(拡散)とAmbient(環境光)カラーは同じにすることが望ましい(全てのUnityビルトイン シェーダはそのようにしている)。

・Lighting On | Off

マテリアルブロックの設定のエフェクトを有効にするためには、Lighting On コマンドでライティングを有効化する必要がある。有効化すると頂点ライティングがおこなわれる.頂点ライティングは各頂点で計算する標準的なDirect3DOpenGLライティングモデルで,もしライティングが無効の場合、色はColor コマンドから直接取得される。Material ブロック、ColorMaterial および SeparateSpecular がLighting Onコマンドによりの有効化される。 頂点/フラグメントプログラムではピクセルライティングが使用されるので,Lighting Onコマンドは意味がない

・Cull Back | Front | Off

カリングは、視点と反対側に向いたポリゴンをレンダリングしない、最適化で,ポリゴンのどちら側をカリングする(描画しない)か制御する。 Back: 視点と反対側のポリゴンをレンダリングしない (デフォルト). Front: 視点と同じ側のポリゴンをレンダリングしない。オブジェクトを反転するのに使用します。 Off: カリングを無効にして、全ての面を描画します。特殊なエフェクトで使用します。 最初にオブジェクトを法線マップ頂点ライティングでレンダリングした後、次にバックフェースを明るいピンクでレンダリングすると法線が反転しないといけないところがハイライトされるので法線のデバッグができる.またガラスなどの透過オブジェクトの場合、しばしばオブジェクトのバックフェースとフロントフェースを描画したい場合があり,そのときにこの方法が使える.

・ZTest

デプステストにより、基本的にはシーンの中で最も近いオブジェクト表面のみ描画されるようにする。これはデプステストの実行方法を決める。デフォルトはLEqual (すでに描画されているオブジェクトと距離が等しいか、より近い場合に描画します、それより遠い場合はオブジェクトで隠します)

・ZWrite On | Off

このオブジェクトのピクセルをデプスバッファに書き込みするか制御(デフォルトはOn )する。もし不透明なオブジェクトを描画する場合、オンにします。もし部分的に透過のエフェクトを描く場合、ZWrite Offに切り替えます。複雑なオブジェクトのフェードをしたいときに有効であることがある.

・Fog { Fog Block }

フォグは生成されたピクセルの色を、カメラからの距離にもとづいた一定のカラーに向けて、ブレンドします。フォグにより、ブレンドされたピクセルのアルファ値は修正せず、RGBのみ変更する。以下のように設定する

Fog { Fog Commands }

Fog Commands(フォグ設定)

Mode Off | Global | Linear | Exp | Exp2
フォグ モードを定義します。デフォルトはGlobalで、フォグがレンダリング設定で有効化されているかによりOffかExp2に変換されます。
Color ColorValue
フォグのカラーを設定します。
Density FloatValue
Exp(指数)モードのフォグの密度を設定します。
Range FloatValue , FloatValue
Linear(線形)モードのフォグのNearおよびFarの範囲を設定します。

具体例は以下

Fog {
  Mode Exp
  Color (1.0,0,0,0)
  Density 0.1
  Range 0.0,10.0
}

デフォルトのフォグ設定はRender Settings にもとづいている.つまりフォグのModeはExp2 あるいはOff、DensityおよびColorはSetting(設定)から同様に取得される。またFragment Programs (フラグメント プログラム)を使用する場合、シェーダのフォグ設定は引き続き適用される。Fixed Function(固定関数)のフォグ機能がないプラットフォームでは、Unityは実行時に、リクエストされたフォグモードをサポートするために、シェーダにパッチ当てる。

・AlphaTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always) CutoffValue
AlphaTest Off

全てのピクセルをレンダリング(デフォルト)。

AlphaTest comparison AlphaValue

アルファ値が特定の範囲にあるピクセルをレンダリングするように、アルファテストを設定する。 Comparison

Greater
ピクセルのアルファ値がAlphaValue より大きい場合のみレンダリング
GEqual
ピクセルのアルファ値がAlphaValue より大きいか等しい場合のみレンダリング
Less
ピクセルのアルファ値がAlphaValue より小さい場合のみレンダリング
LEqual
ピクセルのアルファ値がAlphaValue より小さいか等しい場合のみレンダリング
Equal
ピクセルのアルファ値がAlphaValue と等しい場合のみレンダリング
NotEqual
ピクセルのアルファ値がAlphaValue と等しくない場合のみレンダリング
Always
全てのピクセルをレンダリング。AlphaTest Off と同等の機能
Never
全てのピクセルをレンダリングしない。

AlphaValue AlphaValueは0と1の間の不動小数点数。floatあるいはrangeプロパティへの変数の参照も可能で、その場合は ([VariableName]) と標準的な括弧を使用して記述する。 もし新しいピクセルがすでにレンダリングされているものよりも遠くにある場合,ZTestにより遠くにあるオブジェクトを描画することができない.また木などのオブジェクトではまずアルファ値がしきい値以上の不透明なオブジェクトを Cull offで描画し,その後,Alphaテストを用いてアルファ値がしきい値以下のオブジェクトをZWriteなしで描画するときれいに描画できる.具体例はここのリンク

・Blend SourceBlendMode DestBlendMode

すでに存在しているピクセルに対して、どのように合成するかをブレンディングできめる。

Blend Off

ブレンディングを無効にします。

Blend SrcFactor DstFactor

これはブレンディングを有効にして,生成されたカラー(これから塗る色)にSrcFactor を乗算し画面にすでにあるカラー(フレームバッファにある色)にDstFactor を乗算して、2つを加算する。つまり,見える色=これから塗る色*SrcFactor+現在の色*DstFactor となるようにブレンドする.

Blend SrcFactor DstFactor, SrcFactorA DstFactorA

これはアルファ値をブレンドするのに別なスケール値(SrcFactorA DstFactorA)を使う SrcFactorとDstFactorには以下のものが使われる

One
Oneの値 - これでSourceあるいはDestinationのカラーをそのまま使用したい場合に使用します。
Zero
Zeroの値 - これでSourceあるいはDestinationのカラーを消去したい場合に使用します。
SrcColor
このステージの値はSource Colorの値を乗算します。
SrcAlpha
このステージの値はSource Alphaの値を乗算します。
DstColor
このステージの値はフレームバッファのSource Color
DstAlpha
このステージの値はフレームバッファのSource Alphaの値を乗算します。
OneMinusSrcColor
このステージの値はフレームバッファの(1 - Source Color)を乗算します。
OneMinusSrcAlpha
このステージの値はフレームバッファの(1 - Source Alpha)を乗算します。
OneMinusDstColor
このステージの値はフレームバッファの(1 - Destination Color)を乗算します。
OneMinusDstAlpha
このステージの値はフレームバッファの(1 - Destination Alpha)を乗算します。

よく使われるBlend

Blend SrcAlpha OneMinusSrcAlpha     // Alpha blending
Blend One One                       // Additive
Blend OneMinusDstColor One          // Soft Additive
Blend DstColor Zero                 // Multiplicative
Blend DstColor SrcColor             // 2x Multiplicative

上の様にカラーを加算するのではなく,別の処理を行う。

BlendOp Min | Max | Sub | RevSub
Add
Add source and destination together(Blend one one).
Sub
Subtract source from destination.(現在の色から塗る色を減算)
RevSub
Subtract destination from source(塗る色から現在の色を減算).
Min
Use the smaller of source and destination(塗る色と現在の色の低い方を描画).
Max
Use the larger of source and destination(塗る色と現在の色の高い方を描画).

他の例はここのリンク

・Color Color value

オブジェクトを単色に設定します。カラーは4つのRGBAの値を括弧( )で括るか、あるいはカラープロパティ名を括弧[ ]で括ります。

Pass { Color (1,0,0,0) }
Pass { Color [_ColorProperty] }
・ColorMask RGB | A | 0 | any combination of R, G, B, A

ColorMask RGBと書くと,これより前に描画されてフレームバッファーに格納されているRGBの値を保持する(このPASSではRGBを描画しない).ColorMask 0と書くと何も描画しない.

・Offset OffsetFactor , OffsetUnits

デプスバッファにオフセットを追加する.オフセットは 奥行きのオフセット=m*factor+r*units で計算される(m:その三角形の奥行きの最大の傾き,r:デプス値に差を作り出すことが出来る最小値).例えば、Offset 0, -1により、ポリゴンの勾配を無視してポリゴンをカメラに近づけ、一方でOffset -1, -1はさらに見上げる角度でポリゴンを近づけます。

・SeparateSpecular On | Off

このコマンドは鏡面ライティングをシェーダパスの終わりに追加するため、鏡面ライティングはテクスチャによる影響を受けない。つまりSpecularがテクスチャの色と合成されない.Lighting On が使用されている場合のみエフェクトが有効となる。

・ColorMaterial AmbientAndDiffuse | Emission

メッシュに指定できる頂点カラーを、マテリアルで設定したカラーに優先して、使用する。AmbientAndDiffuse はマテリアルのAmbient、Diffuseの値を頂点カラーで置き換え、EmissionはマテリアルのEmissionの値を頂点カラーで置き換える。

テクスチャ設定(SetTexture)

上記のレンダリング状態の設定の後に、いくつかのテクスチャと、SetTexture コマンドを使用して、適用する合成モードを指定できる。SetTextureコマンドはfragmentシェーダーがある場合、fragmentシェーダーで設定すればよいのでSetTextureは無効となる。PASSのなかに複数のSetTextureコマンド適応させることができ、書いた順番通りにテクスチャの割当が行われる。 以下の文法でテクスチャを割り当てる。TexturePropertyNameはプロパティとして定義したテクスチャの名前を指定する。テクスチャの適用方法はTextureBlock に記述する。

SetTexture [TexturePropertyName] { Texture Block }

テクスチャブロックにはテクスチャを適用する方法を記述する。combine 、matrix 、constantColorの3つのコマンドを指定できる。

combineコマンド
combine src1 * src2
src1とsrc2を乗算。結果はどちらの入力よりも暗くなります。
combine src1 + src2
src1とsrc2を加算。結果はどちらの入力よりも明るくなります
combine src1 - src2
src2をsrc1より減算。
combine src1 +- src2
src1とsrc2を加算、それから0.5を減算 (符号付き加算)。
combine src1 lerp (src2) src3
src3とsrc1の補間をsrc2のアルファを用いて行う。補間の向きが逆であることに留意: アルファが1のときにsrc1、アルファが0のときにsrc3となります。
combine src1 * src2 + src3
src1をsrc2のアルファで乗算しsrc3を加算します。
combine src1 * src2 +- src3
src1をsrc2のアルファで乗算しsrc3と符号付加算します。
combine src1 * src2 - src3
src1をsrc2のアルファで乗算しsrc3を減算します。

src プロパティはprevious 、constant 、primary 、textureのいずれかを指定できる。

  • previous は直前のSetTextureの結果。
  • constantconstantColor で指定した色です。
  • primarylighting calculation の色またはBindChannel している場合は頂点カラー。デフォルトでは、primary カラーは、拡散、環境光、鏡面カラーのsum(合計)である。もしSeparateSpecular On をパスのオプションで指定した場合、鏡面カラーは、合成計算の前ではなく、後に加算される。
  • texture はSetTextureで指定した[_TextureName] のテクスチャ。

conbineコマンドの最後にDouble またはQuad を指定する、例えばconbine primary * texture Doubleと指定することで結果のカラーを2倍または4倍明るく出来きる。またsrcの後にalphaを指定する、例えばtexture alphaやprimary alphaと指定することでアルファのみを取得できる。leap(src)のsrc以外のsrcプロパティの前にone - と指定する、例えばone - textureやone - constantColorと指定することで色を反転させることができる。また以下のようにアルファの計算に別の計算式を指定できる。

SetTexture [_MainTex] { combine previous * texture, previous + texture }
constantColor コマンド

定数カラーを定義し、combineコマンドで使用出来きます。

Properties {
        _Col ("color (RGB)", Color) = (1,1,1,1)
        _MainTex ("Base ", 2D) = "white" {}
}
~~~~
SetTexture [_MainTex] {
         constantColor [_Col]
         combine constant * texture
}
SetTexture [_MainTex] {
         constantColor (1,1,1,1)
         combine constant * texture
}
~~~~
matrix コマンド

テクスチャ座標を、コマンドで指定された行列で、変換します。以下はテクスチャ座標を回転させる例のコード。参考リンク 以下のコードのマテリアルには自身についてるマテリアルをInspectorから指定

using UnityEngine;
using System.Collections;

public class rotation : MonoBehaviour {
 public Material material = null;
 public Matrix4x4 rotateMatrix = Matrix4x4.identity;
 
 void Update () {
  rotateMatrix [0] = rotateMatrix [5] = Mathf.Cos (Time.time);
  rotateMatrix [1] = Mathf.Sin (Time.time);
  rotateMatrix [4] = - rotateMatrix [1];
  renderer.material.SetMatrix ("_RotateMatrix", rotateMatrix);
 }
}

shaderのコードは以下

Shader "Custom/rotationUV" {
 Properties {
  _MainTex ("Base (RGB)", 2D) = "white" {}
 }
 SubShader {
  bindChannels{
   Bind "vertex", vertex
   bind "texcoord", texcoord0
  }
  Pass{
   SetTexture[_MainTex] {
    Matrix[_RotateMatrix]
    combine texture
   }
  }
 }
}

OpenGLOpenGL ES 1.1、Wiiでは各SetTextureのステージの値は0から1の範囲に挟まれています。しかしDirect3D, OpenGL ES 2.0の場合、範囲はそれよりも大きい場合もそうでない場合もあるので注意する必要がある場合がある。現代のfragment shader をサポートするグラフィックスカード(デスクトップ向けは"シェーダモデル2.0" 、モバイル向けはOpenGL ES 2.0)は全てSetTextureモードとテクスチャのステージを少なくとも4(大抵は8)サポートしている。しかし本当に古いハードウェアで実行する場合(PCで2003年以前に製造、モバイル向けでは3GSより前)2テクスチャのステージしかサポートしてない場合があるのでサポートしたカード向けにSubShaders を別に記述する必要がある。

BindChannels

頂点データがグラフィック ハードウェアにどのようにマッピングされるかを指定できる。具体的には2つの用法がある。一つ目はUnityではメッシュデータ(source)に対して2つまでuv座標を設定できる。テクスチャ毎にその2つのuv座標のどちらを使うのかを設定できる。2つ目は頂点カラーを含むメッシュの頂点からーを使うかどうかである。これは頂点シェーダーに影響しないので、頂点シェーダーを使う時はこれは無視され、頂点シェーダ内で制御する必要がある。BindChannelsは以下のように設定する。

// 1 つ目の UV を 1 つ目のテクスチャ ステージに設定させます。
// 2 つ目の UV を 2 つ目のテクスチャ ステージに設定させます。
BindChannels {
   Bind "Vertex", vertex
   Bind "texcoord", texcoord0
   Bind "texcoord1", texcoord1
}
// 1 つ目の UV すべてのテクスチャ ステージに設定させます。
// 頂点色を使用します。
BindChannels {
   Bind "Vertex", vertex
   Bind "texcoord", texcoord
   Bind "Color", color
}

これらはBindChannels { Bind "source", target }の形で設定しなければならない。sourceとtargetの一覧は以下。

ソースは、次のうちのいずれかになります。
  • Vertex: 頂点の位置
  • Normal: 頂点の法線
  • Tangent: 頂点の接線
  • Texcoord: 1 つ目の UV 座標
  • Texcoord1: 2 つ目の UV 座標
  • Color: 頂点ごとの色

ターゲットは、次のうちのいずれかになります。

  • Vertex: 頂点の位置
  • Normal: 頂点の法線
  • Tangent: 頂点の接線
  • Texcoord0, Texcoord1, ...: 対応するテクスチャ ステージに対するテクスチャ座標
  • Texcoord: すべてのテクスチャ ステージに対するテクスチャ座標
  • Color: 頂点の色

ステンシル

ステンシルはピクセル(ピクセルマスク)毎に処理を分けることができ、ピクセルの保存、破棄ができる。ステンシル バッファは通常ピクセル毎の 8 ビット整数であり、値の書き込み、増減が可能。後続のドローコール(描画命令)をステンシルバッファに書き込まれている値に対してテストし、ピクセルシェーダを実行する前にピクセルが破棄されるべきか判断できる。

Pass {
  Stencil {
    Ref 2
    ReadMask 255
    WriteMask 255
    Comp always
    Pass replace
    Fail keep
    ZFail decrWrap
  }
}
Ref referenceValue
比較対象の値(Comp が always 以外の場合)かつ/またはバッファに書き込む値(Pass, Fail, ZFail のいずれかの場合置き換えられる)。0 - 255 の範囲の整数。
ReadMask readMask
0 - 255 の範囲の整数で 8 ビットマスク、バッファのコンテンツで参照値を比較するのに用いられる.つまりRefのreferenceValue に対して readMaskでビットごとにマスクをかけ,Compで参照されるステンシルバッファの値に対して readMaskでマスクをかける. デフォルト値: 255.
WriteMask writeMask
バッファ書き込みに使用される 0 - 255 の範囲の整数で 8 ビットマスク。デフォルト値: 255.
Comp comparisonFunction
バッファの現在のコンテンツを参照値と比較するために使用する関数。デフォルト値: always
Pass stencilOperation
ステンシル テスト(およびデプス テスト)が成功した後のバッファ コンテンツの扱い。デフォルト: keep
Fail stencilOperation
ステンシル テストが失敗した後のバッファ コンテンツの扱い。デフォルト: keep
ZFail stencilOperation
ステンシル テストが成功したがデプス テストが失敗した後のバッファ コンテンツの扱い。デフォルト: keep

Cull Front が指定されてないかぎり Comp, Pass, Fail, ZFail は前面にある物体に適用され、指定されている場合はバックフェースの物体です。明示的に二面のステンシル状態を指定するには CompFront, PassFront, FailFront, ZFailFront (フロント フェースの物体), CompBack, PassBack, FailBack, ZFailBack (バックフェースの物体)とします。 comparisonFunction(比較の関数)には以下のものを指定できる.

Greater
参照値がバッファ値より大きい参照値のピクセルのみレンダリング
GEqual
参照値がバッファ値と等しいまたは大きい参照値のピクセルのみレンダリング
Less
参照値がバッファ値より小さい参照値のピクセルのみレンダリング
LEqual
参照値がバッファ値と等しいまたは小さい参照値のピクセルのみレンダリング
Equal
参照値がバッファ値と等しい参照値のピクセルのみレンダリング
NotEqual
参照値がバッファ値と等しくない参照値のピクセルのみレンダリング
Always
常にステンシル テストは成功
Never
常にステンシル テストは失敗

stencilOperation(ステンシル処理)には以下のものを指定できる

Keep
バッファの現在コンテンツを保持します
Zero
バッファにゼロを書き込みます
Replace
参照値をバッファに書き込みます
IncrSat
バッファの現在値を増分させる。値がすでに 255 の場合は維持する
DecrSat
バッファの現在値を減分させる。値がすでに 0 の場合は維持する
Invert
すべてのビットを無効にする
IncrWrap
バッファの現在値を増分する。値がすでに 255 の場合は 0 にする
DecrWrap
バッファの現在値を減分する。値がすでに 0 の場合は 255 にする

ステンシルはディファード レンダリング パスの中のベース パスおよびライティングパスで使用は制限されており,最終パスにおいてのみ使用できる.よってディファード レンダリングの最終パス,そしてディファード レンダリングの後に描画されるフォワードレンダリングで描画されるオブジェクト(例.透明オブジェクトまたはサーフェイスシェーダのないオブジェクト)に限りステンシルを使用できる. ディファード レンダリング パスは、シーンで使用されているライトマスク レイヤーの数にもとづき、ステンシルバッファのもっとも高い 3 つのビットを使用し、最大で 4 つのもっとも高いビットを使用しているので,ステンシルをディファードレンダリングの後で使うためにはステンシルの読み取りおよび書き込みマスクを使用して"クリーンな" ビットの範囲で処理するか、カメラが強制的にライティングパスの後にステンシル バッファをクリーンするように Camera.clearStencilAfterLightingPass をつかう。

UsePass

名前をつけたパスを参照するには、UsePassをsubshaderの中で使う。
以下は、組み込みのスペキュラシェーダからの名前BASE を持つパスを使用する例。内部では、すべてのパス名が大文字になるため、UsePass は名前を大文字で参照する必要がある。

UsePass "Specular/BASE"

GrabPass

描画されている画面のコンテンツを、テクスチャ内に掴みとる。このテクスチャは後続プロセスで高度な画像ベースのエフェクトに使用できる。 使い方は二つあり、以下である

  • GrabPass { } と指定し、単に現在の画面コンテンツをテクスチャ内に掴みとります。このテクスチャは後続のパスで_GrabTexture でアクセスすることができる。この形式のGrap Passは画面の掴みとり処理を使用する各オブジェクトごとに行う。
  • GrabPass { "TextureName" } により画面コンテンツをテクスチャ内に掴みとるが、フレームごとに1回のみ、指定のテクスチャ名を使用する最初のオブジェクト分のみ、実施する。テクスチャは後続のパスで指定のテクスチャ名でアクセスすることが出来きる。シーンでGrab Passを使用するオブジェクトが複数ある場合に効率的な方法です。

以下は、前にレンダリングされたカラーを反転する高価な方法です:

Shader "GrabPassInvert" {
    SubShader {
        // 全ての不透明な形状の後に、自身を描画します
        Tags { "Queue" = "Transparent" }

        // オブジェクトより後ろのシーンを_GrabTextureに掴み取ります
        GrabPass { }

        // 上で生成したテクスチャでオブジェクトをレンダリングし、カラーを反転します。
        Pass {
            SetTexture [_GrabTexture] { combine one-texture }
        }
    }
}

このシェーダには二つのパスがあり、最初のパスはレンダリングのときにオブジェクトにある全てを掴みとり、次にをそれを二つめのパスで適用します。同じエフェクトはより安価にinvertblend mode を使用して得ることも出来きる。

サブシェーダータグ

サブシェーダータグはいつどのようにしてレンダリングエンジンでレンダリングするのかを決める。以下がサブシェーダータグを指定した例

Tags {
    "Queue" = "Transparent+1"
    "RenderType" = "Opaque"
    "ForceNoShadowCasting" = "True"
    "IgnoreProjector" = "True"
}

Queueタグ

オブジェクトを描画する順番を決める。定義されたQueueタグは以下

  • Background - このレンダリングキューは他より前にレンダリングされます。Skyboxなどに使用されます。
  • Geometry (default) - this is used for most objects. Opaque geometry uses this queue.
  • AlphaTest - アルファテストする形状でこのキューを使用します。Geometry とは別のキューであるのはアルファテストのオブジェクトを全ての不透明のオブジェクトの後に描画するほうが効率的であるためです。
  • Transparent - このレンダリング キューはGeometryAlphaTest の後に、後ろにあるものから先に順番で、レンダリングされます。アルファブレンディングするもの(すなわち、デプスバッファに書き込みしないシェーダ)は全て、ここにあるべきです(ガラス、パーティクル エフェクト)。
  • Overlay - このレンダリングキューはオーバーレイ エフェクトのためです。最後にレンダリングするものはここにあるべきです(例えば、レンズフレア等)。

例えば、透過するオブジェクトにはTransparentを指定する。そうしなければ描画順がおかしくなる。

Shader "Transparent Queue Example" {
     SubShader {
        Tags {"Queue" = "Transparent" }
        Pass {
            // シェーダのBodyの残りを記述...
        }
    }
}

各キューは内部で整数インデックスにより表現され、Background は 1000、 Geometry は 2000、 AlphaTest は 2450、 Transparent は 3000、そしてOverlay は 4000となっている。 もしGeometryの最後だけれども、Transparentよりも前に描画したいものがある場合は以下のように指定する。

Tags { "Queue" = "Geometry+1" }

上記のQueueを指定したshaderのオブジェクトは全ての不透明のオブジェクト(QueueがGeometryであるもの)の後にレンダリングされるが、レンダリングキューが2001(Geometryに1を加算)のため、透過オブジェクト(QueueがTransparentであるもの)より先にレンダリングされます。

RenderTypeタグ

RenderTypeタグはシェーダを定義済みのいくつかのグループに分類します。これはShader Replacement により使用され、Camera Depth Texture を生成することにもに使用される。 使用例(リンク1,リンク2)

ForceNoShadowCasting タグ

"ForceNoShadowCasting"="True"を指定した場合このサブシェーダを使用するオブジェクトはシャドウを投影しない。

IgnoreProjectorタグ

"IgnoreProjectorタグ"="True"を指定した場合このシェーダを使用するオブジェクトはProjectors により影響されない。

その他

Fallback

全てのSubshaderの試行後、実行できるSubshaderがなかった場合、Fallbackで指定したshaderを実行する。Fallback "名前"で指定することができる。Fallback Off と指定するとこのshaderで実行できるSubshaderがなかったとしても警告を出さない

Shader "example" {
    // ここにプロパティおよびサブシェーダを記載します。
    Fallback "Diffuse"
}

CustomEditor

シェーダに対して CustomEditor を定義することが出来る。MaterialEditorを継承したクラスをつくりマテリアルのインスペクター表示をかえることができる。その変更したインスペクターによりshaderの中で条件分岐などができる。参考リンクリファレンス

カテゴリ(Category)

カテゴリにより複数のSubshaderに共通する設定を記述できる。以下はfog をオフににし、blending を追加に指定する必要がある場合の例である

Shader "example" {
Category {
    Fog { Mode Off }
    Blend One One
    SubShader {
        // ...
    }
    SubShader {
        // ...
    }
    // ...
}
}

省略項目

定義済みシェーダとプリプロセッサマクロについては省略。 参考リンク
シェーダ プログラムのバリエーションを複数作成(マルチコンパイルするやつ)は省略。 参考リンク
高度なトピックは省略。 参考リンク


参考webサイト(後半に書いてあることは、ほぼunityの公式リファレンスの引用です)
http://marupeke296.com/UNI_main.html
http://seesaawiki.jp/w/bokkuri_orz/d/Unity3D%20-%20%a5%b7%a5%a7%a1%bc%a5%c0%a1%bc
http://izmiz.hateblo.jp/entry/2014/02/23/223405
http://tips.hecomi.com/entry/2014/03/16/233943
http://docs-jp.unity3d.com/Documentation/Components/SL-Reference.html
http://blog.livedoor.jp/akinow/archives/2012-08.html