ImageEffectで使いやすい2つの座標情報


今後アップする予定のImageEffectの準備記事です。
※今後説明する時にリンクを貼るだけで済むようにするため

ImageEffect用のシェーダで画像を加工する時には
やはり今打ち込もうとしているpixelは、画面のどの辺りのpixelか、という情報が必要になるわけですが、
それを求める上で有用な座標情報が有るので紹介しておきます。

画面テクスチャ座標

「何を今更」感が有るけれども一応説明。
Projectツリーで右クリック > Create > Shader > Image Effect Shader で作ったそのままのコードをベースに説明します。

FragmentShader(frag())内の

fixed4 col = tex2D(_MainTex, i.uv);

の i.uv です。
こちら、画面の左下から右上にかけて(0,0)〜(1,1)値が入っています。

i.uv.x確認

下記のコードで確認してみます。

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                col.rgb += i.uv.x;
                return col;
            }


i.uv.xを色に加算する事で、左端が元の色、右端が真っ白になりました。

i.uv.y確認

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                col.rgb += i.uv.y;
                return col;
            }


i.uv.yを色に加算する事で、下端が元の色、上端が真っ白になりました。

ビューポート座標

頂点の座標変換についての説明は今回の記事では省きますが、
グラフィックデータにおける頂点位置座標は、複数の座標変換を経てビューポート空間のビューポート座標を指す値へと変換されます。
ビューポート座標とは、具体的には頂点シェーダのコードの

o.vertex = UnityObjectToClipPos(v.vertex);

o.vertexの部分にあたります。
o.vertex.xyには画面左下から右上にかけて(-1,-1)〜(1,1)の値が入っています。

ビューポート座標をFragmentShaderで参照するために

o.vertexの値はそのままではFragmentShaderに持っていけないので、uv値のデータを広げてそこに間借りさせてもらいます。
v2f(VertexToFragment)の float2 uv を float4 uv に変更します

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

頂点シェーダで増やした uv.zw に vertex.xy を入れます。

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

これでFragmentShaderでビューポート座標を参照する準備ができました。

vertex.x(i.uv.z)を確認

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv.xy);
                col.rgb += i.uv.z;
                return col;
            }


左端が暗くなり、右端が真っ白になることが確認できます。

vertex.y(i.uv.w)を確認

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv.xy);
                col.rgb += i.uv.w;
                return col;
            }


下端が真っ黒、上端が真っ白になることが確認できます。


できるだけ図解しつつ2つの座標を説明&確認しました。
今後投稿するImageEffectで上記2つの座標を利用する際に、この記事へのリンクを貼ろうと考えています。