Cg/HLSL でシェーダープロパティーを参照する
内蔵のシェーダー include ファイル

頂点プログラムへ頂点データの流し込み

Cg/HLSL 頂点プログラム のために、メッシュ 頂点データは頂点シェーダー関数に入力データとして渡されます。各入力には、それを指定するセマンティクス が必要です。例えば、入力データ POSITION は頂点位置、NORMAL は頂点法線ベクトル、など。 Mesh vertex data is passed as inputs to the vertex shader function. Each input needs to have semantic speficied for it: for example, POSITION input is the vertex position, and NORMAL is the vertex normal.

頂点データの流し込みは、1つずつデータを渡す代わりに、しばしば 1つの構造体として宣言されます。一般的に使用される頂点構造体は、UnityCG.cginc の include ファイル で定義され、たいていそれだけで十分です。構造体には以下のものがあります。 listing them one by one. Several commonly used vertex structures are defined in UnityCG.cginc include file, and in most cases it’s enough just to use those. The structures are:

  • appdata_base: 位置、法線および 1 つのテクスチャ座標で構成されます。
  • appdata_tan: 位置、接線、法線および 1 つのテクスチャ座標で構成されます。
  • appdata_full: 位置、接線、法線、4 つのテクスチャ座標および色で構成されています。

例: このシェーダーは、その法線に基づいて、メッシュに色を付け、頂点プログラム入力として、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 セマンティクス によって特定され、以下のリストに挙げられているものの 1つです。 vertex structure yourself, or add input parameters to the vertex shader. Vertex data is identified by Cg/HLSL semantics, and must be from the following list:

  • POSITION は頂点位置、一般的には float3float4 です。
  • NORMAL は通常の頂点で、一般的には float3 です。
  • TEXCOORD0 は、第 1 の UV 座標で、一般的に、float2, float3, float4 です。
  • TEXCOORD1, TEXCOORD2, TEXCOORD3 は、それぞれ第 2、第 3、第 4 の UV 座標です。
  • TANGENT は、(ノーマルマッピングで使用される)接線ベクトルで、一般的には、 float4 です。
  • COLOR は、頂点ごとの色で、一般的には、 float4 です。

頂点シェーダーへの流し込みで、メッシュデータのコンポーネントにデータがない場合、デフォルトが 1 の .w コンポーネントを除き、残りには 0 が入力されます。例えば、メッシュテクスチャ座標はたいてい x と y コンポーネントだけの 2D ベクトルです。頂点シェーダーが float4 を宣言し TEXCOORD0 セマンティクスがある場合、頂点シェーダーは (x,y,0,1) の値を受け取ります。 shader input, the rest are filled with zeroes, except for the .w component which defaults to 1. For example, mesh texture coordinates are often 2D vectors with just x and y components. If a vertex shader declares a float4 input with TEXCOORD0 semantic, the value received by the vertex shader will contain (x,y,0,1).

UV の表示

次のシェーダーの例は、(構造 appdata で定義された) 頂点シェーダー入力として、頂点位置と 1 つ目のテクスチャ座標を使用します。このシェーダーは、メッシュの UV 座標をデバッグするのに非常に便利です。

Shader "Debug/UV 1" {
SubShader {
    Pass {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include "UnityCG.cginc"

        // 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 = UnityObjectToClipPos(v.vertex );
            o.uv = float4( v.texcoord.xy, 0, 0 );
            return o;
        }
        
        half4 frag( v2f i ) : SV_Target {
            half4 c = frac( i.uv );
            if (any(saturate(i.uv) - i.uv))
                c.b = 0.5;
            return c;
        }
        ENDCG
    }
}
}

ここでは、UV 座標は、赤色と緑色で表示され、0 〜 1 の範囲外にある座標には、さらに青色が適用されます。

トーラスノットモデルに適用された UV1 シェーダーをデバッグ
トーラスノットモデルに適用された UV1 シェーダーをデバッグ

同様に、このシェーダーは、モデルの 2 つ目の UV を表示します。

Shader "Debug/UV 2" {
SubShader {
    Pass {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include "UnityCG.cginc"

        // 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 = UnityObjectToClipPos(v.vertex );
            o.uv = float4( v.texcoord1.xy, 0, 0 );
            return o;
        }
        
        half4 frag( v2f i ) : SV_Target {
            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 {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include "UnityCG.cginc"

        // 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 = UnityObjectToClipPos(v.vertex );
            o.color = v.color;
            return o;
        }
        
        fixed4 frag (v2f i) : SV_Target { return i.color; }
        ENDCG
    }
}
}
色にベイクされた照明が設定されたトーラスノットモデルに適用されたカラーシェーダーをデバッグ
色にベイクされた照明が設定されたトーラスノットモデルに適用されたカラーシェーダーをデバッグ

法線の表示

次のシェーダーは、(構造 appdata で定義された) 頂点シェーダー入力として、頂点位置と法線を使用します。法線の X、Y、Z 成分は、RGB 色として表示されます。法線成分は、–1 から 1 の範囲なので、法線をスケールおよびバイアスし、出力される色は –1 から 1 の範囲で表示可能です。

Shader "Debug/Normals" {
SubShader {
    Pass {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include "UnityCG.cginc"

        // 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 = 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
    }
}
}
トーラスノットモデルに適用された法線シェーダーをデバッグ。モデルにハードシェーディングエッジがあるのが分かるでしょう。
トーラスノットモデルに適用された法線シェーダーをデバッグ。モデルにハードシェーディングエッジがあるのが分かるでしょう。

接線と従法線の表示

接線および従法線ベクトルは、法線マッピングに使用されます。Unity では、接線ベクトルは、頂点に格納され、従法線ベクトルは、法線および接線から派生します。

次のシェーダーは、(構造 appdata で定義された) 頂点シェーダー入力として、頂点位置と接線を使用します。接線の X、Y、Z 成分は、R、G、B 色として表示されます。法線成分は、–1 から 1 の範囲なので、それらを –1 から 1 の範囲でスケールおよびバイアスし、出力される色は –1 から 1 の範囲で表示可能です。

Shader "Debug/Tangents" {
SubShader {
    Pass {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include "UnityCG.cginc"

        // 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 = UnityObjectToClipPos(v.vertex );
            o.color = v.tangent * 0.5 + 0.5;
            return o;
        }
        
        fixed4 frag (v2f i) : SV_Target { return i.color; }
        ENDCG
    }
}
}
トーラスノットモデルに適用された接線シェーダーをデバッグ。
トーラスノットモデルに適用された接線シェーダーをデバッグ。

次のシェーダーでは、従接線が表示されています。頂点座標、法線そして接線の値が頂点入力として使われています。従接線(従法線とも呼ばれる)は 法線と接線の値から計算されています。表示可能な 0 から 1 の範囲でスケールおよびバイアスされる必要があります。

Shader "Debug/Bitangents" {
SubShader {
    Pass {
        Fog { Mode Off }
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #include "UnityCG.cginc"

        // 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 = UnityObjectToClipPos(v.vertex );
            // calculate bitangent
            float3 bitangent = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
            o.color.xyz = bitangent * 0.5 + 0.5;
            o.color.w = 1.0;
            return o;
        }
        
        fixed4 frag (v2f i) : SV_Target { return i.color; }
        ENDCG
    }
}
}
トーラスノットモデルに適用された従法線シェーダーをデバッグ。
トーラスノットモデルに適用された従法線シェーダーをデバッグ。

参考文書

Cg/HLSL でシェーダープロパティーを参照する
内蔵のシェーダー include ファイル