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

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

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

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

FragmentShader(frag())内の

```glsl
fixed4 col = tex2D(_MainTex, i.uv);
```
の　i.uv　です。
こちら、画面の左下から右上にかけて(0,0)〜(1,1)値が入っています。
![スクリーンショット 2020-04-18 1.48.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61266/7ff3ec6c-ca1a-f166-0a96-4e491751ef2a.png)


## i.uv.x確認
下記のコードで確認してみます。

```glsl
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                col.rgb += i.uv.x;
                return col;
            }
```
![スクリーンショット 2020-04-18 1.45.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61266/6d97914b-3221-0593-5c2e-c1d44712b71e.png)
i.uv.xを色に加算する事で、左端が元の色、右端が真っ白になりました。

## i.uv.y確認

```glsl
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                col.rgb += i.uv.y;
                return col;
            }
```
![スクリーンショット 2020-04-18 1.46.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61266/87404d43-152d-316e-14da-606410be1c81.png)
i.uv.yを色に加算する事で、下端が元の色、上端が真っ白になりました。

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

```glsl
o.vertex = UnityObjectToClipPos(v.vertex);
```
o.vertexの部分にあたります。
o.vertex.xyには画面左下から右上にかけて(-1,-1)〜(1,1)の値が入っています。
![スクリーンショット 2020-04-18 1.48.48_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61266/17969d78-33d6-af26-8548-31905e0d3bfa.png)
## ビューポート座標をFragmentShaderで参照するために
o.vertexの値はそのままではFragmentShaderに持っていけないので、uv値のデータを広げてそこに間借りさせてもらいます。
v2f(VertexToFragment)の　float2 uv　を　float4 uv　に変更します

```glsl
struct v2f
{
    float4 uv : TEXCOORD0;
    float4 vertex : SV_POSITION;
};
```
頂点シェーダで増やした　uv.zw　に　vertex.xy　を入れます。

```glsl
            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)を確認

```glsl
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv.xy);
                col.rgb += i.uv.z;
                return col;
            }
```
![スクリーンショット 2020-04-18 1.46.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61266/ee77c118-215a-3272-0894-0c89221203b8.png)
左端が暗くなり、右端が真っ白になることが確認できます。
## vertex.y(i.uv.w)を確認

```glsl
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv.xy);
                col.rgb += i.uv.w;
                return col;
            }
```
![スクリーンショット 2020-04-18 1.47.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61266/2abdc084-d38f-6bd3-f751-b353c7705b5b.png)
下端が真っ黒、上端が真っ白になることが確認できます。

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