Cg/HLSL 頂点プログラム に対し、メッシュ の頂点データは頂点シェーダー関数への入力で渡されます。入力ごとに セマンティック を指定する必要があります。例えば、POSITION 入力は頂点位置、NORMAL は頂点法線です。
しばしば、頂点のデータ入力は 1 つずつ記述されず、構造体で宣言されます。
よく使用される頂点構造体は、UnityCG.cginc include ファイル で定義され、たいてい、それを使えば十分です。それらの構造体は以下の通りです。
appdata_base: 位置、法線および 1 つのテクスチャ座標で構成されます。appdata_tan: 位置、接線、法線および 1 つのテクスチャ座標で構成されます。appdata_full: 位置、接線、法線、4 つのテクスチャ座標および色で構成されています。appdata_img: 位置、ひとつのテクスチャ座標、頂点シェーダー入力。このシェーダーは、その法線に基づいて、メッシュに色を付け、頂点プログラム入力として、appdata_base を使用します。
Shader "VertexInputSimple" {
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
fixed4 color : COLOR;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.color.xyz = v.normal * 0.5 + 0.5;
o.color.w = 1.0;
return o;
}
fixed4 frag (v2f i) : SV_Target { return i.color; }
ENDCG
}
}
}
異なる頂点データにアクセスするには、自分で頂点構造体を宣言するか、入力パラメータを頂点シェーダーに追加する必要があります。頂点データは Cg/HLSL セマンティクス によって識別され、以下のいずれかに該当する必要があります。
POSITION は頂点位置で、通常はfloat3またはfloat4です。NORMAL は頂点法線で、一般的には float3 です。TEXCOORD0 は最初の UV 座標で、通常は float2、float3、または float4 です。TEXCOORD1、TEXCOORD2、TEXCOORD3 は、それぞれ第 2、第 3、第 4 の UV 座標です。TANGENT は、(法線マッピングで使用される) 接線ベクトルで、一般的には float4 です。COLOR は、頂点ごとの色で、一般的には float4 です。メッシュデータが、頂点シェーダー入力で必要とされるよりも少ない数の要素しか持たない場合、デフォルトで 1 に設定されている .w 要素を除いて残りの部分をゼロで埋めます。例えば、メッシュテクスチャ座標は、しばしば、x と y コンポーネントしか持たない 2D ベクトルです。頂点シェーダーが TEXCOORD0 セマンティックで float4 の入力を宣言する場合、その頂点シェーダーによって受け取る値には (x,y,0,1) が含まれます。
そのため、最良のクロスプラットフォームの対応として、
セマンティクス上、頂点出力とフラグメント入力を TEXCOORDn セマンティクスにするのが一般的です。
Unity は以下をサポートしています。
VPOS- レンダリングされているピクセルの位置。シェーダーには #pragma target 3.0 コンパイルディレクティブが必須であり、クリップスペース位置を別個の “out” 変数として出力する必要があります。ポータビリティを最大限に高めるには、大半のプラットフォームで float4 であるタイプ UNITY_VPOS_TYPE を使用します。VFACE - レンダリングされる面がカメラの方を向いているか、カメラとは違う方向を向いているか。シェーダーには #pragma target 3.0 コンパイルディレクティブが必要です。SV_VertexID - 処理されている頂点のインデックス。シェーダーには #pragma target 3.5 コンパイルディレクティブが必要です。これらのテクニックを使って、ビルトインレンダーパイプラインで頂点データを視覚化する例は、頂点データの視覚化 を参照してください。
Direct3D 11 はすべてのシェーダー変数を “constant buffer” (定数バッファ) にグループ分けします。Unity ビルトインの変数のほとんどはすでにグループ分けされてますが、自身で作成するシェーダーの変数については、予想される更新頻度に応じて、別の constant buffer に格納することが最適です。
それには、CBUFFER_START(name) マクロと CBUFFER_END マクロを使用します。
CBUFFER_START(MyRarelyUpdatedVariables)
float4 _SomeGlobalValue;
CBUFFER_END
GPU 計算バッファ または グラフィックスバッファ を使用して変数の値を設定する場合は、そのバッファおよび定数バッファのデータレイアウトが、ビルドするすべてのグラフィックス API と一致することを確認してください。詳細については、GPU バッファと定数バッファの使用 を参照してください。
注意定数バッファに構造体を追加することはできません。
頂点からフラグメントシェーダーに情報を渡すために、使用できる Interpolator 変数の総数には制限があります。制限はプラットフォームおよび GPU によって異なり、一般的な目安は以下のとおりです。
float4 変数に 2 つのテクスチャ座標を渡すことができます (1 つ目の座標は .xy、2 つ目の座標は .zw)。#pragma target 3.0)#pragma target 4.0)ターゲットハードウェアに関係なく、パフォーマンス上の理由で、できる限り少ない数の Interpolator を使うほうが一般的によいとされています。