このチュートリアルでは、独自のシェーダーを作成するための最初のステップを学習します。ゲームの見た目を制御し、グラフィックスのパフォーマンスを最適化するためです。
Unity は強力なシェーディングとマテリアルの言語、 ShaderLab を装備しています。 形式的には、Direct3D Effects (.FX) 言語に似ていて、 マテリアル を表示するために必要なものすべてを表現します。
シェーダーは、Unity のマテリアルインスペクターで表示されるプロパティーと、異なる種類のグラフィックスハードウェアにレンダリングする複数シェーダーの実装 (サブシェーダー) 、そして頂点と、フラグメントプログラムを設定します。シェーダープログラムは高レベルの Cg/HLSL プログラミング言語で書かれています。
ここでは、いわゆる「固定関数」表記を使用して、_非常に単純な_シェーダーの書き方について説明します。シェーダー: 頂点とフラグメントプログラムで、頂点とフラグメントのシェーダープログラム について紹介します。 OpenGL や、Direct3D レンダリングステータスの基本を理解し、HLSL、Cg、GLSL、Metal のうち、いずれかのシェーダープログラミングの知識があるという前提で説明します。
シェーダーを新規作成するには、メニューバーから Assets > Create > Shader > Unlit Shader を選択するか、既存のシェーダーをコピーし、そこから作業します。新しいシェーダーは、プロジェクトウィンドウ をダブルクリックすることで編集できます。
Unity では、_非常に単純な_シェーダーをいわゆる「固定関数」表記で作成する方法があります。簡単に説明するために、まず、これから始めましょう。 内部では、シェーダーのインポート時に、固定関数シェーダーは標準的な頂点とフラグメントのプログラム に変換されます。
非常に基本的なシェーダーから始めましょう。
Shader "Tutorial/Basic" {
Properties {
_Color ("Main Color", Color) = (1,0.5,0.5,1)
}
SubShader {
Pass {
Material {
Diffuse [_Color]
}
Lighting On
}
}
}
この簡単なシェーダーは、もっとも基本的なシェーダーの 1 つを例示します。これは Main Color という色プロパティーを定義し、これにピンク色 (赤=100% 緑=50% 青=50% アルファ=100%) のデフォルト値を割り当てます。次に Pass を呼び出してオブジェクトをレンダリングし、このパスで、デフューズマテリアルコンポーネントをプロパティー _Color に設定し、頂点ごとのライティングをオンにします。
このシェーダーをテストするには、ドロップダウンメニューからシェーダーを選択し (Tutorial->Basic)、そのマテリアルをオブジェクトに割り当てます。マテリアルインスペクターで色を微調整し、変更を確認します。次は、もっと複雑なことに挑戦しましょう。
既存の複雑なシェーダーを開く場合、よい概要を得るのは若干難しい場合があります。最初に、Unity に同胞の組み込み VertexLit シェーダーを分解してみましょう。このシェーダーは、固定関数パイプラインを使用して、標準の頂点ごとのライティングを実行します。
Shader "VertexLit" {
Properties {
_Color ("Main Color", Color) = (1,1,1,0.5)
_SpecColor ("Spec Color", Color) = (1,1,1,1)
_Emission ("Emmisive Color", Color) = (0,0,0,0)
_Shininess ("Shininess", Range (0.01, 1)) = 0.7
_MainTex ("Base (RGB)", 2D) = "white" { }
}
SubShader {
Pass {
Material {
Diffuse [_Color]
Ambient [_Color]
Shininess [_Shininess]
Specular [_SpecColor]
Emission [_Emission]
}
Lighting On
SeparateSpecular On
SetTexture [_MainTex] {
constantColor [_Color]
Combine texture * primary DOUBLE, texture * constant
}
}
}
}
すべてのシェーダーは、キーワード Shader で始まり、その後にシェーダーの名前を表す文字列が続きます。これは Inspector に表示される名前です。このシェーダーのすべてのコードは、その後の波括弧内に入れる必要があるということです。{ } (ブロックと呼ばれます)。
このシェーダーは、 SubShader ブロックが後にくる Properties ブロックで構成されます。これらについては各自後述します。
シェーダーブロックの最初で、マテリアル インスペクター でアーティストが編集できるプロパティーを定義できます。 VertexLit の例では、このプロパティーは次のように見えます。
プロパティーは、Properties ブロック内の個々の行に一覧表示されます。各プロパティーは、内部名 (Color、 MainTex) で始まります。この後の括弧内には、インスペクターで表示される名前とプロパティーの型がきます。その後、このプロパティーのデフォルト値が一覧表示されます。
型のリストは、ShaderLab :プロパティー にあります。デフォルト値は、プロパティーのタイプによって決まります。色の例では、デフォルト値は、4 つの成分のベクトルになるはずです。
プロパティーを定義したので、実際のシェーダーを記述する準備ができました。
次に進む前に、シェーダーファイルの基本的な構造を定義しましょう。
グラフィックハードウェアによって、機能が異なります。例えば、グラフィックカードによって断片プログラムをサポートしているものとしていないものがあります。パスごとに 4 つのテクスチャを置くものもあれば、2 つまたは 1 つしかおかないものもあります。ユーザーの持っているハードウェアが何であろうと最大限に活用できるようにするため、シェーダーは、複数の SubShaders を含むことができます。Unity がシェーダーをレンダリングすると、すべてのサブシェーダーに展開し、ハードウェアがサポートする最初のサブシェーダーを使用します。
Shader "Structure Example" {
Properties { /* ...shader properties... }
SubShader {
// ...subshader that requires fancy DX11 / GLES3.1 hardware...
}
SubShader {
// ...subshader that requires DX9 SM3 / GLES3 hardware...
}
SubShader {
// ...subshader that might look ugly but runs on anything :)
}
}
このシステムにより、Unity はすべての既存のハードウェアをサポートし、それぞれでの質を最大化できます。しかし、シェーダーは多少長くなります。
各サブシェーダーブロック内で、すべてのパスが共有するレンダリング状態を設定し、レンダリングパス自体を定義します。使用できるコマンドの完全なリストは、ShaderLab :サブシェーダー にあります。
各サブシェーダーは、パスの集合です。各パスに対して、オブジェクトジオメトリがレンダリングされるため、少なくとも 1 つのパスが必要です。ここでの VertexLit シェーダーは、次の 1 つのパスがあります。
// ...snip...
Pass {
Material {
Diffuse [_Color]
Ambient [_Color]
Shininess [_Shininess]
Specular [_SpecColor]
Emission [_Emission]
}
Lighting On
SeparateSpecular On
SetTexture [_MainTex] {
constantColor [_Color]
Combine texture * primary DOUBLE, texture * constant
}
}
// ...snip...
パスで定義されたコマンドは、グラフィックハードウェアを設定し、特定の方法でジオメトリをレンダリングします。
上記の例では、 Material ブロックは、固定関数ライティングマテリアル設定にプロパティー値を結合します。コマンド Lighting On は、標準の頂点ライティングをオンにし、 SeparateSpecular On は、スペキュラハイライトに対して、個々の色の使用を有効にします。
これまでのコマンドはすべて、固定関数 OpenGL/Direct3D ハードウェアモデルに対して、直接マッピングします。詳細については、OpenGL red book を参照してください。
次のコマンド SetTexture は非常に重要です。これらのコマンドは、使用したいテクスチャと混合方法を定義し、結合し、レンダリングで適用します。 SetTexture コマンドの後には、使用したいテクスチャのプロパティー名がきます (ここでは _MainTex)。この後には、テクスチャの適用方法を定義する combiner block がきます。コンバイナブロック内のコマンドは、画面上でレンダリングされる各ピクセルに対して実行されます。
このブロック内で、一定の色値、つまり、マテリアルの色である _Color を設定します。この一定の色はを以下で使用します。
次のコマンドでは、テクスチャと色値の混合方法を指定します。これを、テクスチャを色や他のテクスチャとブレンドする方法を指定する Combine コマンドで行います。一般に以下のような感じになります。 Combine ColorPart、AlphaPart
ここでは、 ColorPart と AlphaPart が、色 (RGB) とアルファ (A) 成分のブレンディングをそれぞれ定義します。 AlphaPart が省略されると、 ColorPart と同じブレンディングを使用します。
頂点リットの例で、 Combine texture * primary DOUBLE、texture * constant
ここでは、 texture は、現在のテクスチャ (ここでは _MainTex) から来ている色です。これは primary 頂点色で乗算 (*) されます。最初の色は、頂点ライティング色で、上記マテリアル色から計算されます。最後に、結果が 2 で乗算され、ライティング強度が増します ( DOUBLE )。アルファ値 (コンマの後) は、 constant 値で乗算された texture になります (上記の constantColor で設定)。もう 1 つのよく使用されるコンバイナモードは previous と呼ばれます (このシェーダーでは使用されません)。これは、前の SetTexture 手順の結果であり、複数のテクスチャおよび/または色を相互に結合するのに使用できます。
頂点リットシェーダーは、レンダリングされたライティング強度が 2 倍になるよう、標準の頂点ライティングを設定し、テクスチャコンバイナを設定します。
シェーダーにより多くのパスを入れることができ、これらのパスは次々とレンダリングされます。しかし、現在、必要な効果があるため、これは不要です。高度な機能を使用しないため、必要なサブシェーダーは 1 つだけです。この特定のシェーダーは、Unity がサポートしているグラフィックカードで機能します。
頂点リットシェーダーは、考えられる中でもっとも基本的なシェーダーです。ハードウェア固有の操作を使用せず、また ShaderLab や Cg/HLSL が提供する特殊でクールなコマンドも使用しませんでした。
次のチャプター では、Cg/HLSL 言語を使用したカスタムの頂点や断片プログラムの記述法の説明から始めます。