頂点プログラムへ頂点データの流し込み
Cg/HLSL vertex programs に対して,頂点データを構造として渡す必要があります。 幾つかのよく使用される頂点構造は,UnityCG.cginc include file で定義され,ほとんどの場合,使用するだけなら十分です。 構造は以下のようになります。
appdata_base
: 頂点は,位置,法線および 1 つのテクスチャ座標で構成されます。appdata_tan
: 頂点は,位置,接線,法線および 1 つのテクスチャ座標で構成されます。appdata_full
: vertex consists of position, tangent, normal, two texture coordinates and color.例えば,このシェーダは,その法線に基づいて,メッシュに色を付け,頂点プログラム入力として,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 = mul (UNITY_MATRIX_MVP, v.vertex);
o.color.xyz = v.normal * 0.5 + 0.5;
o.color.w = 1.0;
return o;
}
fixed4 frag (v2f i) : COLOR0 { return i.color; }
ENDCG
}
}
}
各種頂点データにアクセスしたい場合は,頂点構造を自身で宣言する必要があります。 この構造 メンバーは,次のリストから選択する必要があります 。
次のシェーダのサンプルは,(構造 appdata で定義された) 頂点シェーダ入力として,頂点位置と 1 つ目のテクスチャ座標を使用します。 メッシュの UV 座標をデバッグするのに非常に便利です。 UV 座標は,赤色および緑色で表示され,0 〜 1 の範囲外にある座標には,更に青色が適用されます。
Shader "Debug/UV 1" {
SubShader {
Pass {
Fog { Mode Off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// vertex input: position, UV
struct appdata {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
};
v2f vert (appdata v) {
v2f o;
o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
o.uv = float4( v.texcoord.xy, 0, 0 );
return o;
}
half4 frag( v2f i ) : COLOR {
half4 c = frac( i.uv );
if (any(saturate(i.uv) - i.uv))
c.b = 0.5;
return c;
}
ENDCG
}
}
}
同様に,このシェーダは,モデルの 2 つ目の UV を表示します:
Shader "Debug/UV 2" {
SubShader {
Pass {
Fog { Mode Off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// vertex input: position, second UV
struct appdata {
float4 vertex : POSITION;
float4 texcoord1 : TEXCOORD1;
};
struct v2f {
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
};
v2f vert (appdata v) {
v2f o;
o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
o.uv = float4( v.texcoord1.xy, 0, 0 );
return o;
}
half4 frag( v2f i ) : COLOR {
half4 c = frac( i.uv );
if (any(saturate(i.uv) - i.uv))
c.b = 0.5;
return c;
}
ENDCG
}
}
}
次のシェーダは,(構造 appdata で定義された) 頂点シェーダ入力として,頂点位置と頂点ごとの色を使用します。
Shader "Debug/Vertex color" {
SubShader {
Pass {
Fog { Mode Off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// vertex input: position, color
struct appdata {
float4 vertex : POSITION;
fixed4 color : COLOR;
};
struct v2f {
float4 pos : SV_POSITION;
fixed4 color : COLOR;
};
v2f vert (appdata v) {
v2f o;
o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
o.color = v.color;
return o;
}
fixed4 frag (v2f i) : COLOR0 { return i.color; }
ENDCG
}
}
}
次のシェーダは,(構造 appdata で定義された) 頂点シェーダ入力として,頂点位置と法線を使用します。 法線の X,Y,Z 成分は,R,G,B 色として表示されます。 法線成分は,–1..1 の範囲で,色は –1..1 の範囲にあるため,出力色が表示可能な 0..1 の範囲になるよう,法線をスケールおよびバイアスします。
Shader "Debug/Normals" {
SubShader {
Pass {
Fog { Mode Off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// vertex input: position, normal
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f {
float4 pos : SV_POSITION;
fixed4 color : COLOR;
};
v2f vert (appdata v) {
v2f o;
o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
o.color.xyz = v.normal * 0.5 + 0.5;
o.color.w = 1.0;
return o;
}
fixed4 frag (v2f i) : COLOR0 { return i.color; }
ENDCG
}
}
}
接線および従法線ベクトルは,法線マッピングに使用されます。 Unity では,接線ベクトルは,頂点に格納され,従法線ベクトルは,法線および接線から派生します。
次のシェーダは,(構造 appdata で定義された) 頂点シェーダ入力として,頂点位置と接線を使用します。 接線の X,Y,Z 成分は,R,G,B 色として表示されます。 法線成分は,–1..1 の範囲で,色は –1..1 の範囲にあるため,出力色が表示可能な 0..1 の範囲になるよう,法線をスケールおよびバイアスします。
Shader "Debug/Tangents" {
SubShader {
Pass {
Fog { Mode Off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// vertex input: position, tangent
struct appdata {
float4 vertex : POSITION;
float4 tangent : TANGENT;
};
struct v2f {
float4 pos : SV_POSITION;
fixed4 color : COLOR;
};
v2f vert (appdata v) {
v2f o;
o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
o.color = v.tangent * 0.5 + 0.5;
return o;
}
fixed4 frag (v2f i) : COLOR0 { return i.color; }
ENDCG
}
}
}
次のシェーダは従法線を表示します。 これは,頂点入力として,位置,法線および接線を使用します。 従法線は,法線および接線から計算されます。 法線または接線と同様,表示可能な 0..1 の範囲になるよう,スケールおよびバイアスする必要があります。
Shader "Debug/Binormals" {
SubShader {
Pass {
Fog { Mode Off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// vertex input: position, normal, tangent
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
};
struct v2f {
float4 pos : SV_POSITION;
float4 color : COLOR;
};
v2f vert (appdata v) {
v2f o;
o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
// calculate binormal
float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
o.color.xyz = binormal * 0.5 + 0.5;
o.color.w = 1.0;
return o;
}
fixed4 frag (v2f i) : COLOR0 { return i.color; }
ENDCG
}
}
}