トーフメモ

主にゲーム制作

3秒でわかる「頂点シェーダー」【Unity】

f:id:tofgame:20190428235628j:plain

頂点シェーダーとは

(主に)頂点の座標等を操作するシェーダーです!
Vertex Shader(バーテックスシェーダー)とも言います。
頂点シェーダー部分はHLSL言語で書かれています。

デフォルトのシェーダーを作る

「Project」上で右クリックして、 Create -> Shader -> UnlitShader と選択するとシンプルなシェーダーができます。
f:id:tofgame:20190503233442p:plain

デフォルトのUnlitShaderからFog周りを省いたものが以下のコードです。

Shader "Unlit/NewUnlitShader"{
    Properties{
        _MainTex("Texture", 2D) = "white" {}
    }

    SubShader{
        Tags { "RenderType" = "Opaque" }
        LOD 100

	Pass{
	    CGPROGRAM
	    #pragma vertex vert
	    #pragma fragment frag

	    //入力用の構造体
	    struct appdata {
               float4 vertex : POSITION; //頂点の座標
               float2 uv : TEXCOORD0; //頂点に設定されたuv座標
	    };

	    //出力の構造体
	    struct v2f {
                float4 vertex : SV_POSITION; //頂点の座標
                float2 uv : TEXCOORD0; //頂点に設定されたuv座標
            };

            //頂点シェーダー
            v2f vert(appdata v) {
	        v2f o;
	        o.vertex = UnityObjectToClipPos(v.vertex); //頂点の座標をクリップ空間での座標に変換
	        o.uv = v.uv; //uv座標はそのまま
	        return o;
            }

            sampler2D _MainTex;

            //フラグメントシェーダー
            fixed4 frag(v2f i) : SV_Target{
	        fixed4 col = tex2D(_MainTex, i.uv);
	        return col;
            }
	    
	    ENDCG
        }
    }
}

このコードから、頂点シェーダーに関わる部分を抜粋します。

頂点シェーダーに関わる部分

#pragma vertex vert 

ここで頂点シェーダーメソッドを設定しています。

struct appdata {
    float4 vertex : POSITION; 
    float2 uv : TEXCOORD0; 
};

頂点シェーダーに渡す引数を構造体で定義します。
変数のコロン(:)の後に書かれている大文字のキーワードは、「セマンティクス」といいます。
レンダリングの過程で渡される、もしくは渡すデータがあらかじめ決まっていて、どの引数にどのデータが対応しているかをここで書きます。
この構造体では入力用のセマンティクスを対応させます。
「POSITION」は座標データで、「TEXCOORD0」が頂点に対応しているuv座標です。

struct v2f {
    float4 vertex : SV_POSITION;
    float2 uv : TEXCOORD0;
};

頂点シェーダーが渡す値を構造体で定義します。
ここでは出力用のセマンティクスを対応させます。
「SV_POSITION」は座標データで、「TEXCOORD0」が頂点に対応しているuv座標です。

v2f vert(appdata v) {
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = v.uv;
    return o;
}

頂点シェーダーのメソッドです。
ここで実際の処理をします。
UnityObjectToClipPos()を使って頂点座標をクリップ空間座標へと変換します。
クリップ座標系については以下のページを参照してください。
blog.natade.net

また、ここではuv座標は特に加工せずそのまま渡しています。

そしてフラグメントシェーダーへ

頂点シェーダーでの処理が終わったら、カリングやラスタライズを経て「フラグメントシェーダー」の処理に進みます。

(参考)入出力セマンティクスの種類

docs.microsoft.com